Mysql经常崩溃

时间:2013-08-08 10:11:15

标签: mysql pdo

我的Mysql服务器经常崩溃,我需要使用“service mysqld start”命令重启mysql。 我检查了mysql错误日志文件。

130807 22:59:47 mysqld_safe Number of processes running now: 0
130807 22:59:47 mysqld_safe mysqld restarted
130807 22:59:47 [Note] Plugin 'FEDERATED' is disabled.
130807 22:59:47 InnoDB: The InnoDB memory heap is disabled
130807 22:59:47 InnoDB: Mutexes and rw_locks use GCC atomic builtins
130807 22:59:47 InnoDB: Compressed tables use zlib 1.2.5
130807 22:59:47 InnoDB: Using Linux native AIO
130807 22:59:47 InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
130807 22:59:47 InnoDB: Completed initialization of buffer pool
130807 22:59:47 InnoDB: Fatal error: cannot allocate memory for the buffer pool
130807 22:59:47 [ERROR] Plugin 'InnoDB' init function returned error.
130807 22:59:47 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
130807 22:59:47 [ERROR] Unknown/unsupported storage engine: InnoDB
130807 22:59:47 [ERROR] Aborting

130807 22:59:47 [Note] /usr/libexec/mysqld: Shutdown complete

130807 22:59:47 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended

我有大约10,000个用户,我有一个拥有10,000个表的数据库。这些表用于记录用户状态。而且,当我创建一个新的用户表时,我使用以下代码与PDO。

$statusTable = "status_".$uid;
$qstr = "CREATE TABLE IF NOT EXISTS `status`.`$statusTable` (
    `prim_id` INT( 5 ) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `message` VARCHAR( 600 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
    `created_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE = INNODB";
$db->query($qstr);

这段代码会导致mysql崩溃吗?我使用615MB RAM的EC2实例。谢谢!

3 个答案:

答案 0 :(得分:2)

除了非常糟糕的数据库设计之外,您之前的问题/问题似乎是posted and answered

答案 1 :(得分:0)

简单答案:您不需要为每个用户创建新表来跟踪其状态。您正在使用他们的$uid,因此,您可以使用带有列uid的单个表来跟踪其数据。然后,当您要获取其数据时,请使用$uid,例如

SELECT * FROM user_data
WHERE uid=$uid

此外,您可以设置cron调度程序以在MySQL崩溃时重新启动它。

* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld

详细答案:

这是一个重要的问题,特别是对于使用非常小的VPS(例如1GB或更少的RAM)的用户。如果MySQL退出,则可能是服务器配置(Apache | nginx)或MySQL配置有问题。 DOS攻击可能导致系统资源使用率增加(见图)。最终结果是MySQL进程被内核关闭。对于长期解决方案,应该考虑优化您的Apache或MySQL配置。

System resources spike causing RAM spike (just before 6pm) and system resources spike causing only a CPU spike Midnight on Tue 18

还有其他一些关于Stack Overflow这些主题的讨论,以及MySQL手册和Percona博客:

MySQL手册-MySQL如何使用内存:

https://dev.mysql.com/doc/refman/8.0/en/memory-use.html

Percona-配置最佳MySQL内存使用的最佳做法:

https://www.percona.com/blog/2016/05/03/best-practices-for-configuring-optimal-mysql-memory-usage/

如何使用MySQLTuner优化MySQL性能:

https://www.linode.com/docs/databases/mysql/how-to-optimize-mysql-performance-using-mysqltuner/

Apache内存使用情况配置:

https://serverfault.com/questions/254436/apache-memory-usage-optimization

Apache性能调整手册:

https://httpd.apache.org/docs/2.4/misc/perf-tuning.html

调整Apache服务器:

https://www.linode.com/docs/web-servers/apache-tips-and-tricks/tuning-your-apache-server/

但是,关于您的原始问题,是的,您可以编写一个临时解决方案的脚本,以检查MySQL服务是否已加载并处于活动状态,如果未加载并处于活动状态则将重新启动MySQL。

您没有提及正在使用的操作系统。这将有助于给您特定的命令。我会给你一个CentOS linux的例子。
查看命令systemctl status mysql的以下输出。您可以在顶部看到该服务已加载活动

[root@centos-mysql-demo ~]# systemctl status mysqld
● mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2019-06-18 18:28:18 UTC; 924ms ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/en/using-systemd.html
  Process: 3350 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
  Process: 3273 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 3353 (mysqld)
   CGroup: /system.slice/mysqld.service
           └─3353 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid

Jun 18 18:28:11 centos-mysql-demo systemd[1]: Starting MySQL Server...
Jun 18 18:28:18 centos-mysql-demo systemd[1]: Started MySQL Server.

如果未加载该服务,则显示以下命令:

systemctl status mysqld || systemctl restart mysqld 

将完成重新启动过程的技巧。您可以提出以下建议:

* * * * * systemctl status mysqld || systemctl restart mysqld

但是,如果mysql已加载,但服务未活动,则您的cron将不执行任何操作。因此,您应该使用更详细的命令,例如:

* * * * * systemctl is-active --quiet mysqld || systemctl restart mysqld

在这种情况下,如果服务已加载无效,例如DOS攻击可能离开您的mysql服务的状态,则该命令还将重新启动mysql。使用--quiet标志仅指定命令仅返回状态代码,而不向屏幕输出任何内容。如果省略--quiet标志,您将看到activeinactive的状态输出。

您还可以创建一些交换空间,以向服务器添加更多可用的RAM资源,例如:

sudo dd if=/dev/zero of=/swapfile count=2096 bs=1MiB
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon --show
swapon --summary
free -h

答案 2 :(得分:-1)

我认为问题是你有很多与数据库的并行连接导致了这个问题。问题不在于表,问题在于它周围的架构。