MySQL 在 SQL 上崩溃
Posted
技术标签:
【中文标题】MySQL 在 SQL 上崩溃【英文标题】:MySQL Crashing on SQL 【发布时间】:2011-09-18 11:52:28 【问题描述】:在过去的 4 天里,mysql 不断在运行脚本时崩溃,比如每天一次
这是错误日志
key_buffer_size=134217728
read_buffer_size=1048576
max_used_connections=39
max_threads=100
threads_connected=34
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 336508 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
thd: 0x92025f38
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x95dce36c thread_stack 0x30000
/usr/sbin/mysqld(my_print_stacktrace+0x2d) [0x6b65ad]
/usr/sbin/mysqld(handle_segfault+0x494) [0x3823d4]
[0x110400]
/usr/sbin/mysqld(MYSQLparse(void*)+0x6aa) [0x3b42da]
/usr/sbin/mysqld(mysql_parse(THD*, char const*, unsigned int, char const**)+0x23e) [0x39ce6e]
/usr/sbin/mysqld(dispatch_command(enum_server_command, THD*, char*, unsigned int)+0xf35) [0x39df25]
/usr/sbin/mysqld(do_command(THD*)+0xf3) [0x39f0e3]
/usr/sbin/mysqld(handle_one_connection+0x2a0) [0x38dbd0]
/lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0x93d96e]
/lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xd78a4e]
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort...
thd->query at 0x86982ef4 is an invalid pointer
thd->thread_id=2906
thd->killed=NOT_KILLED
该盒子在 2GB RAM 上运行,根据我的计算,它不应该有最大内存的问题。我专门将内存要求降低到最低限度,但仍然出现错误。
mysql> show variables like "sort_buffer%";
+------------------+---------+
| Variable_name | Value |
+------------------+---------+
| sort_buffer_size | 1048576 |
+------------------+---------+
今天在这个 SQL 查询上崩溃了
ALTER TABLE FieldDefaultValue MODIFY value_field varchar(2000) CHARACTER SET utf8 collate utf8_bin;
有人有类似经历吗?
编辑:
有问题的表实际上不包含太多数据,数据库有更大的表:
mysql> desc fielddefaultvalue;
+----------------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+---------------+------+-----+---------+----------------+
| fielddefaultvalue_Id | bigint(20) | NO | PRI | NULL | auto_increment |
| version | bigint(20) | NO | | NULL | |
| value_field | varchar(2000) | YES | MUL | NULL | |
| optimistic_version | bigint(20) | NO | | NULL | |
| property_fk | bigint(20) | YES | MUL | NULL | |
| esg_fk | bigint(20) | YES | MUL | NULL | |
+----------------------+---------------+------+-----+---------+----------------+
6 rows in set (0.02 sec)
mysql> select count(*) from fielddefaultvalue;
+----------+
| count(*) |
+----------+
| 690 |
+----------+
1 row in set (0.00 sec)
多次插入 (400-500) 小数据也会失败,但并非总是如此,同一个脚本可以正常运行一次或崩溃
编辑 2:崩溃恢复后,错误日志还报告:
InnoDB: which exceeds the log group capacity 9433498.
InnoDB: If you are using big BLOB or TEXT rows, you must set the
InnoDB: combined size of log files at least 10 times bigger than the
InnoDB: largest such row.
我的.cnf
lower_case_table_names = 1
key_buffer = 16M
key_buffer_size = 128M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
max_connections = 100
table_cache = 512
thread_concurrency = 4
sort_buffer_size = 1M
read_buffer_size = 1M
table_open_cache = 512
read_rnd_buffer_size = 8M
innodb_file_per_table = 1
open_files_limit = 65536
default_character_set=utf8
query_cache_limit = 1M
query_cache_size = 64M
expire_logs_days = 10
max_binlog_size = 250M
innodb_buffer_pool_size = 256M
innodb_additional_mem_pool_size = 20M
编辑:5 小时后
它只是在同一个“常规”脚本上再次崩溃,它是一个日期列上的 25.000 行更新脚本。
同样的错误信息:
InnoDB: Log scan progressed past the checkpoint lsn 186 4056481576
110620 17:30:52 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Read
有趣的是,我今天运行了这个脚本并没有失败,但现在成功了。
【问题讨论】:
哪个版本,它是 innoDB 还是 MyISAM 表? 你是在运行 MySQL Cluster 还是只是 MySQL Server? 它是带有简单 MySQL 服务器的 innodb 数据库。需要提到的是,这主要是一个开发人员的测试环境,它在导入大型 SQL 转储(400 MB 或更大)时没有问题,但在执行多次插入或更改多行表的 SQL 上会崩溃 key_buffer 和 key_buffer_size 是相同的设置,所以设置它们是多余的。特别是对于不同的价值观。 【参考方案1】:最可能的解释是地址空间不足;请张贴您的整个 my.cnf。
在生产环境中运行 32 位操作系统并不是一个好主意。
但是,你应该做的是:
-
在非生产机器上重现相同 MySQL 版本的故障
检查您是否使用 Oracle 提供的正确支持的当前版本。如果不是,请安装其中一个并重现问题。如果您正在运行 Redhat(或类似的),那么您可以使用 Oracle 的 RPM。他们还在 tar.gz 文件中提供了一些其他发行版的包和二进制文件。您的软件包供应商可能会使用一些不可靠的补丁来修补 MySQL。我从不在生产环境中运行 OEM MySQL 版本。
您似乎在运行 32 位。确保您没有用完地址空间。
如果您可以在 支持 操作系统上使用 标准 Oracle 构建重现该错误,那么您不会耗尽内存/地址空间,也没有硬件故障,然后您可以将 bug 提交给 Oracle。
最好的办法是用最少的数据/表大小重现测试用例。
【讨论】:
这是我们的开发人员使用的 ubuntu 服务器盒(它不是生产环境,但对开发人员来说很重要)。我们使用的是 5.1.41,因为我们不需要测试 5.5 对我们的软件的作用。过去3-4个月没有引起任何问题,自从安装以来,它只是过去4-5天出现了问题。当时没有更改任何配置。我不是这些问题的专家,我如何检查它是否没有用完地址空间。 我们有 5.1.41 在各种 linux / windows 机器(生产环境)上运行,从未引起任何问题,绝对不是这个。我曾想过可能是一个有问题的 ram 模块,但我想在解决这个问题之前排除一个错误的 mysql 配置。【参考方案2】:听起来您的 innodb_log_file_size 不够大 - 尝试在 my.cnf 中使用 256 MB: innodb_log_file_size=256M
您需要彻底关闭它,删除旧的日志文件,然后重新启动 - mysql 将重新创建新的日志文件。
【讨论】:
【参考方案3】:奇怪...我不知道 ALTER TABLE 在 MySQL 上的实际优化程度如何。也许它会消耗很多电力。如果表包含大量数据,请尝试将所有数据移动到临时表中并清空主表。然后做你的改变表并将数据推回。如果它必须对每一行进行工作,那么您可以像这样拆分工作,一次做几条记录。
【讨论】:
该表实际上并没有包含很多数据,与其他表相比code
以上是关于MySQL 在 SQL 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章