-2

我的 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 内存的 EC2 实例。谢谢!!

4

3 回答 3

2

除了非常糟糕的数据库设计之外,您的问题/问题似乎之前已经发布和回答过。

于 2013-08-08T10:21:26.593 回答
1

简单的答案:您不需要为每个用户创建一个新表来跟踪他们的状态。您正在使用他们的$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 配置。

系统资源峰值导致 RAM 峰值(下午 6 点之前)和系统资源峰值仅导致 CPU 峰值在星期二 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 

将完成重新启动该过程的技巧。你可以cron :

* * * * * 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
于 2019-06-18T19:33:09.657 回答
-1

我认为问题是您的数据库有许多并行连接,这导致了这个问题。问题不在于桌子,问题在于围绕它的架构。

于 2013-08-08T10:19:23.023 回答