赞
踩
2.MySQL连接不上
3.MySQL打开文件失败
4.MySQL挂起(hung)
5.MySQL崩溃(crash)
6.忘记用户密码
1.无法访问系统资源
2.参数设置错误
检查访问文件和目录的权限 测试:
# sudo -u mysql touch /home/mysql/data/filename
- mysql> system sudo -u mysql touch /home/mysql/data/a
- mysql> create table t1 (id int primary key,n varchar(10)) data directory='/home/mysql/data';
- ERROR 1030(HY000):Got error 168 from storage engine
- 原因:mysqld进程的访问被Linux的selinux或apparmor给阻止
- # mysqld --no-defaults --console --user mysql
- 2020-11-03T03:36:07.519419Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19)starting as process 21171
- 2020-11-03T03:36:07.740347Z 1 (ERROR] [MY-012574] nnoDB] Unable to lock ./ibdata1 error: 11
- 原因:另外一个 mysqld 进程已经启动并占用了对应的文件
- $ mysqld --verbose --help| grep "Default options "-A 1
- Default options are read from the following files in the given order:
- /etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
- $ mysqld --print-defaults
- usr/sbin/mysqld would have been started with the following arguments:
- ....
- 这个命令和 my_print_defaults mysqld 完全是等价的,只不过后者的显示方式是一行一个参数
在mysqld 后加上第一个参数--no-defaults,这个参数的作用是通知 mysld 在启动的时候不要读任何参数文件;
第二个参数是--console,这个参数会把错误信息输出到屏幕上,这个参数带来的一个弊端是所有的信息都输出到屏幕上,让屏幕显得比较乱,但对于我们调试却是很方便的;
第三个参数是--log-error-verbosity=3,这个参数会显示详细的日志;
然后再在后面加上有把握的参数,可以一次只加一个参数,然后启动 mysqld,采用排除法逐步找出错误的参数
- # mysqld --no-defaults --console --log-error-verbosity=3 --user mysql --gtid_mode=on
- ......
- 2020-11-03T07:14:21.632851Z 0 [ERROR][MY-010912] [Server] GTID_MODE = ON requiresENFORCE GTID CONSISTENCY = ON.
- .......
- 需要我们同时设置参数GTID MODE和 ENFORCE GTID CONSISTENCY 同时为 on
MySQL服务器上的进程 mysqld 没有正常运行
客户端不能和进程mysqld 通信
账户密码的问题
遇到这种情况首先到服务器上看看 mysgld 进程是否活着,采用的命令是
mysqladmin ping 或 ps -ef l grep mysqld
进行网络连通的测试:
telnet localhost 3306
如果本地能通,再到客户端的机器上把 localhost 换成 MySQL 服务器的 ip 地址进行测试
如果不能通,通常有两种原因:
一种原因是 OS或网络的问题,或者是防火墙:
另一种原因是mysqld 自身根本没有侦听客户端的连接请求
使用参数 --skip-networking 跳过侦听客户端的网络连接
使用参数 --bind-address 后面增加对客户端访问IP 地址的限制
对客户端访问IP 地址的不进行限制
- # mysqld --no-defaults --console --user mysql --skip-networking &
- # netstat -plunt|grep 3306
- #
- # mysqld --no-defaults --user mysql --bind-address=127.0.0.1 &
- # netstat -plunt|grep 3306
- tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 22767/mysqld
- tcp6 0 0:::33060 :::* LISTEN 22767/mysqld
- # mysqld --no-defaults --user mysql --bind-address='192.168.17.40' &
- # netstat -plunt|grep 3306
- tcp 0 0 192.168.17.40:3306 0.0.0.0:* LISTEN 23053/mysqld
- tcp6 0 0:::33060 :::* LISTEN 23053/mysqld
默认为 2,设置为3可以记录更多的信息,这个参数可以联机设置
Permitted Message Priorities | log_error_verbosity Value |
ERROR | 1 |
ERROR,WARNING | 2 |
ERROR,WARNING,INFORMATION | 3 |
- root@scutech:~# mysql -uroot -perrorpassword
- mysql: [Warning] Using a password on the command line interface can be insecure.
- ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
- 在MySQL的 errorlog 里有这样的记录:
- 2020-11-03T07:59:40.720835Z 7 [Note] [MY-010926] [Server] Access denied for user 'root'@'localhost' (using password: YES)
- 如果把参数 --log-error-verbosity 设置成的默认值 2 时是没有这个提示的,也就说没有 note类型的信息。
- ERROR 1130 (HY000): Host '192.168.17.149' is not allowed to connect to this MySQL server
- 注意账户错误时,提示是“is not allowed to connect to this MySQL server”,而密码错误时是“Access denied for user ”
MySQL中的一个账户是由 user 和 host 两个部分组成,在 MySQL 中有个 mysql 数据库,里面有个user表,表中 Host和 User 为两个主键列 (primary key),唯一表示一个用户。像这种情况通常是 host 字段部分是 localhost,把它改成通配符"%"即可。
- mysql> update mysql.user set host='%' where user='root';
- Query OK, 1 row affected (0.01 sec)
- Rows matched: 1 Changed: 1 Warnings: 0
- mysql> flush privileges;
- Query OK, 0 rows affected (0.02 sec)
- shell> perror 23
- OS error code 23: File table overflow
- shell> perror 24
- OS error code 24: Too many open files
- shell> perror 11
- OS error code 11: Resource temporarily unavailable
- OS 中统计已经打开的文件
- ls -l /proc/`pidof mysqld`/fd|wc
- MySQL数据库里统计已经打开的文件数查看状态参数
- Open_table_definitions 和 Open_tables
一种是减少 MySQL同时打开的文件数量,例如减少参数 table_open_cache 或/和 max_connections。
另一种方法是增加 MySQL 可以打开的文件数量,即增加 MySQL 的参数open_files_limit。
MySQL 启动时这个参数起作用,在运行的时候系统会自动调整,会根据下面两个公式选择其中一个大的数:
10 + max_connections +(table_open_cache* 2)
max_connections*5
MySQL8.0.19 版本之后就直接用操作系统的限制
- 配置文件 /etc/security/limits.conf
- 检查进程的限制:
- cat /proc/`pidof mysqld`/limits|grep "Max open files'
使用OS层的 top sar free iostat vmstat 等查看系统资源的瓶颈
$ mysqladmin -i 5 processlist status
mysql> show engine innodb status \G
关注一下几个部分:
LATEST DETECTED DEADLOCK
TRANSACTIONS
FILE I/O
- 临时解决,kill 造成死锁的连接:
- for id in `mysqladmin processlist | grep -i locked | awk '{print $1}'`
- do
- mysqladmin kill ${id}
- done
- 根本解决,修改应用
- delete update 避免使用非索引字段为条件
- 避免批量 delete update
- 检查 MySQL 服务状态 $ service mysql status
- 检查 MySQL中的uptime 状态 mysql> show global status like 'uptime';
- 使用 ps 检查进程启动时间 $ ps -eo pid,user,args,etime|grep mysqld
- 检查 MySQL日志 找关键字“ready for connections”
- 使用 kill -9 杀死 mysqld 进程系统会自动重新启动,而只使用 kill 命令则不会重新启动,因为执行 kill 命令,系统会发送一个SIGTERM 信号给 mysqld,MySQL数据库会正常关闭,日志中会出现类似下面的记录:
- 2020-10-26T09:06:48.435181Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.19) MySQL Community Server - GPL.
- 1
MySQL数据库 crash 的最常见原因有两个
1.MySQL的 bug
2.MySQL申请系统资源失败或内存泄漏。
MySQL数据库 crash 的最常见的一个原因当然是 MySQL 的bug。95%的 bug 都是和具体的sql 相关,通常是 MySQL crash 前执行的最后一个sql 有问题,因此定位 bug 时应打开 general query log,根据最后一个 sql 来查找线索。
1.仔细阅读 MySQL的错误日志,这个日志里面的一些程序调试信息看起来很让人困惑,但静下心来仔细看,很多时候会找到线索:
2.打开 general query log,找到最后一个 sql 访问的表或索引,检查这个表或索引,如果有问题就重建,通常可以解决问题。
3.使用 strace、pstack、pmap、gdb 分析mysqld 的代码,可能需要打开 core dump;
4.使用CMake 的选项-DWITH_DEBUG=1 重新编译 mysqld,然后运行重新编译后的 mysqld查看trace 文件、error log 进行排错
- 全局内存
- innodb_buffer_pool_size innodb_log_buffer_size thread_cache_size table_open_cache table_definition_cache key_buffer_size
- 线程内存
- binlog_cache_size thread_stack
- 单次操作内存
- join_buffer_size read_buffer_size read_rnd_buffer_size tmp_table_size sort_buffer_size
SELECT (@@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@key_buffer_size+ @@max_connections*(@@binlog_cache_size + @@thread_stack + @@read_buffer_size+ @@read_rnd_buffer_size + @@sort_buffer_size + @@join_buffer_size + @@tmp_table_size)/ 1024 /1024 AS MAX MEM MB;
echo 1> /proc/sys/vm/drop_caches
0:0是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存
从长远看还是要修改对应的参数进行解决。
- mysql: Out of memory at line 42, 'malloc.c'
- mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
- ERROR 2008: MySQL client ran out of memory
1.检查正在运行的 SQL,看看您真的需要这么大的返回结果集吗?
2.允许 mysql 时加上 --quick 选项,这会减少客户端单次收到的返回集,但会增加 mysqld 的负载。
skip-grant-tables
init-file
- 在默认的参数文件中加上skip-grant-tables
- root@infokist:/etc/mysql# service mysql restart
- root@infokist:/etc/mysql# mysql
- mysql> update mysql.user set authentication_string=password('dingjia') where user='root';
- Query OK, 1 row affected, 1 warning (0.00 sec)
- Rows matched:1 Changed:1 Warnings: 1
- mysql> flush privileges;
- Query OK, 0 rows affected (0.01 sec)
- 加了 skip-grant-tables 参数后会自动加上skip-networking 不允许远程连接
- 移除了 PASSWORD() 函数
- 修改密码的方法是用 alter user 的命令修改密码,但注意要载入权限表后才能alter user
- mysql> alter user root identified by 'dingjia';
- ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so itcannot execute this statement
- mysql> flush privileges;
- Query OK, 0 rows affected (0.07 sec)
- mysql> alter user root@localhost identified by 'dingjia';
- Query OK, 0 rows affected (0.02 sec)、
- 使用 -init-file 参数启动实例,类似: mysqld_safe --init-file=/tmp/chpw.sql&
- 在chpw.sql文件里面写上密码修改语句:
- alter user 'root'@'localhost' dentified by 'dingjia';
- 实例启动成功后,密码即修改完毕
- 这种方法只会重启一次 MySQL实例,而且基本上不存在安全隐患
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。