Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EC2 MySQL crashing continuously

I have an EC2 instance set on the x64 amazon linux ami.

I am using PHP & Wordpress with W3 total cache & php-apc backed by MySQL to test a blog which can handle a decent number of connections relatively cheaply.

However, my mysql keeps crashing out.

Taken from the /var/log/mysqld.log

120912  8:44:24 InnoDB: Completed initialization of buffer pool
120912  8:44:24 InnoDB: Fatal error: cannot allocate memory for the buffer pool
120912  8:44:24 [ERROR] Plugin 'InnoDB' init function returned error.
120912  8:44:24 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
120912  8:44:24 [ERROR] Unknown/unsupported storage engine: InnoDB

Anyone know the reason this could be happening?

Current memory usage (below)

[root@ip-obscure mysql]# free -m
             total       used       free     shared    buffers     cached
Mem:           594        363        230          0          3         67
-/+ buffers/cache:        293        301
Swap:            0          0          0
like image 253
David Avatar asked Sep 12 '12 08:09

David


People also ask

Why does MySQL keeps crashing?

You are running many mysqld servers using the same data directory on a system that does not support good file system locks (normally handled by the lockd lock manager), or you are running multiple servers with external locking disabled.

Can I run MySQL in EC2?

Follow the steps below to install MySQL on AWS EC2: Step 1: Create an AWS Elastic Cloud Compute Instance.. Step 2: Start the EC2 instance that you have created in Step 1. Step 3: Connect to your EC2 Instance by clicking on Connect Button.

Why EC2 instance is getting stopped automatically?

The following are the most common reasons: The instance failed one or both of its status checks. The underlying hardware hosting your instance was faulty and Amazon EC2 restarted the instance to move it to new, healthy hardware. Scheduled maintenance occurred on your instance that required a reboot.


3 Answers

Be wary of concluding you do not have enough memory , yes that is the error you see but that is also a symptom not the cause. Wait before paying for a bigger instance, the problem will only go away for some time until the memory fills up again.

Be wary of creating SWAP files, again you are only bandaging the symptoms.

Be wary too of changing config settings (and limiting the performance of your apache or mysql) which has been working just fine for some time but only now suddenly the server will not stay up for long at all.

Think how could that really be settings? if there was a badly optimised setting or a memory leak in PHP it would have failed consistently after the same sort of time period. So assuming you have not just recently installed new modules and have had had a pretty static environment for some time it is unlikely to be a memory leak or settings. Obviously if you have just been installing new modules disabling them should always be a first step

Be wary of splitting the database to another server, this will not solve the problem in the same way as buying a bigger server doesnt solve the problem. Yes each function will get more memory initially but then.....

Be wary of migrating from apache to another http server such as NginX, a drastic step, which may solve the problem..... but for the wrong reasons

I was guilty of most of these and raised many a false hope, until I looked at the apache /var/log/httpd/ACCESS_LOG file and saw that my site was being hit several times a second from the same IP looking for a file called XMLRPC.PHP, some kind of DDOS attack well known in Wordpress circles.

example access_log entry ....

191.96.249.80 - - [21/Nov/2016:20:27:53 +0000] "POST /xmlrpc.php HTTP/1.0" 200 370

each time it is received apache tries to instantiate a child process to service that request. Before long you run out of memory and apache starts failing to fork a new process and mysql gives up trying to allocate memory space to the buffer pool. You basically run out of memory and all these requests grind your server to a halt.

to solve ths I changed the .htaccess file to deny access to the file from that IP, and my server returned to normal operation immediatly.

example .htaccess

<Files xmlrpc.php>

order allow,deny

deny from 191.96.249.80

allow from all

</Files>"

Hope my hard won findings help someone else!

Obviously if your access log is not showing a DDOS effect, it might be something else, try all the above! ;-) but I have now seen several a wordpress/apache site affliicted with this attack. ... same IP too! Its a pity Amazon AWS does not allow blacklists in its security groups. [sigh]

like image 60
Binthere Avatar answered Oct 29 '22 23:10

Binthere


I imagine your instance is lacking memory needed to do what you are wanting to do.

Have you considered using RDS for MySQL? That is really the preferred methodology in the AWS world (at least for DB's taht don't require a high degree of custom configuration) and will give you much better performance than running MySQL on EBS storage (which I assume you are doing as otherwise you have no way of persisting your DB content).

like image 4
Mike Brant Avatar answered Oct 29 '22 23:10

Mike Brant


Well, it's December 2016 and apparently this is still around.

A client reported that one of his sites (not managed by my company) was down and asked for support. When we started looking for the problem it became apparent that his webserver was being DDoS'ed due to this vulnerability.

The mitigation procedures are pretty much covered in the other answers, so I just want to add my 2 cents: besides .htaccess rules, you can also block the IPs originating the requests with iptables. See here for a quick overview. Basically what you get from this is:

  1. Apache (or whatever you're using) doesn't consume overhead resources replying with 403 to the attack origin or even log them (saving lots of disk space) - your machine will simply ignore the requests;

  2. If you realise that the requests are originating from the same subnet, you can block the requests per subnet origin, hitting many of the compromised machines attacking you all at the same time.

This obviously has the pitfall of not verifying the validity of the requests being made, but that is also a factor in the other solutions, as well as xmlrpc.php still being unaccessible. Also, whatever file requested from those origins will be rejected.

Basically, I grep'ed requests to xmlrpc.php being logged by Apache and counted which were the most offending ones:

cat  /var/log/apache2/access.log | grep xmlrpc.php | awk '{print $1;}' | sort -n | uniq -c | sort -nr | head -20

This will print out a sorted list of the top 20 most offending IPs. I noticed that in my top 5 most offending ones, 4 came from the same subnet.

Then, after you've identified which ones you want to block, assuming they have an IP like 123.123.123.123:

sudo iptables -A INPUT -s 123.123.123.123 -j DROP

Or, if you want to target a certain subnet:

sudo iptables -A INPUT -s 123.123.123.123/24 -j DROP

The /24 indicates you're targeting 123.123.123.XXX where XXX can be whatever combination. Repeat this procedure as much as you see fit. I ended blocking 90%+ of the requests with just a couple of rules, but YMMV.

Also, note that this will stop logging those offending requests unless you remove the iptables rules you set up above.

Hope this helps!

like image 2
Joum Avatar answered Oct 29 '22 23:10

Joum