一、前景
Mysql作为开源数据库的中坚力量之一,虽然目前已被甲骨文收购,面临闭源风险,但是mysql扔是我们运维工作中最常面对的工作,那如何做好mysql运维工作,甚至做好mysql的基础运维,都是维稳业务持久层的关键,故本文收集相关资料整理MySQL运维工作常用的命令,以作记录,供日常运维时参考查证。
二、Mysql运维
MySQL运维工作常用命令和操作主要包括:对MySQL数据库状态的查看、性能的优化(连接数,存储,集群等),MySQL表及索引的检查、分析、修复、优化,MySQL数据库的导出导入、冷热备份等。
2.1、工具篇
常用工具:
1)myisampack:压缩MySQL的MyISAM表以产生更小的只读表的一个工具。myisampack可以压缩MyISAM表来解决空间占用过大的问题。myisampack分别压缩表中的每一列。通常,myisampack可以将数据文件压缩到40%-70%。当以后使用表时,解压缩列需要的信息被读入内存。当访问具体的记录时性能会更好,因为你只需要解压缩一个记录。
2)mysqlaccess:检查访问主机名、用户名和数据库组合的权限的脚本。它可作为MySQL的一个诊断工具,检查访问权限的主机名、用户名和数据库组合。其检查功能只访问user、db和host这3个表,而不检查在tables_priv、columns_priv或procs_priv表等信息;
3)mysqladmin:用于管理MySQL服务器的客户端。它是执行管理操作的客户端程序,可以用它来创建或删除数据库,重载授权表,将表刷新到硬盘上,以及重新打开日志文件,检索版本、进程,以及服务器的状态信息;
4)mysqlbinlog:从二进制日志读取执行过的语句的工具。MySQL数据库服务器生成的所有更新了的数据或者已经潜在更新了的数据的----所有语句----均以二进制日志文件存在,文件内容是由很多event group组成的,每个group中包含一组event,其中又分事务性和非事务性,对应不同的event,每一条信息都是一条event,语句以“事件”的形式保存,它描述数据更改。要想检查这些文本格式的文件,应必须使用mysqlbinlog工具,可通过这些二进制日志帮助MySQL数据库从崩溃中恢复。
5)mysqlcheck:检查、修复、分析以及优化表的表维护客户端程序。其主要用来检查和修复MyISAM表,mysqlcheck还可以优化和分析表。mysqlcheck的功能类似myisamchk,但其工作不同。mysqlcheck和myisamchk主要差别是**当mysqld服务器在运行时必须使用mysqlcheck**,而myisamchk应用于服务器没有运行时。使用mysqlcheck的好处是不需要停止服务器来检查或修复表,mysqlcheck为用户提供了一种方便的使用SQL语句CHECK TABLE、REPAIR TABLE、ANALYZE TABLE和OPTIMIZE TABLE的方式。
6)mysqldump:将MySQL数据库转储到一个文件(例如SQL语句或tab分隔符文本文件)的客户端程序。可用来转储数据库或搜集数据库进行备份或将数据转移到另一个SQL服务器(不一定是一个MySQL服务器)。转储包含创建表和/或装载表的SQL语句。如果你在服务器上进行备份,并且表均为MyISAM表,应考虑使用mysqlhotcopy,因为可以更快地进行备份和恢复。
7)mysqlhotcopy:当MySQL数据服务器在运行时,快速备份MyISAM或ISAM表的工具。mysqlhotcopy实际其是一个Perl脚本,它使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表的最快的途径,但它只能运行在数据库目录所在的机器上。mysqlhotcopy只用于备份MyISAM且运行在Unix和NetWare中。
8)mysqlimport:使用LOAD DATA INFILE将文本文件导入相关表的客户端程序。该程序r位于mysql/bin目录中,它是一个非常有效的数据导入工具。mysqlimport客户端提供了LOAD DATA INFILEQL语句的一个命令行接口。这个命令可以让我们很轻松的把有结果规律的文本导入到MySQL数据库中。
9)mysqlshow:显示数据库、表、列以及索引相关信息的客户端程序。它可用来很快地查找存在哪些数据库,数据库中的表,表中的列或索引。mysqlshow为一些SQL显示语句提供了一个命令行界面,相同的信息可以通过直接使用那些语句获得。
10)myisamchk:MyISAM表维护实用工具。它可用来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。myisamchk的功能类似mysqlcheck,但其工作不同。myisamchk和mysqlcheck主要差别是当mysqld服务器在运行时必须使用mysqlcheck,而myisamchk应用于服务器没有运行时。
2.2、命令行篇
2.2.1 mysql之【查】:
show processlist; 查询数据库的链接数
show global status 查询数据库全局状态
show global status like ‘uptime’ 查询数据库运行时间
show global variables 查询数据库全局变量
show global variables like ‘max_allowed_packet’ 查询数据库允许最大数据包
show variables like ‘%char%’; 查看mysql字符集设置
show character set; 查看mysql支持的所有字符集
set variables_name=value; 用来修改全局变量
show engines; 查看当前数据库支持的引擎和默认的数据库引擎:
show OPEN TABLES where In_use > 0; ##查询是否锁表
## mysql基本信息查询
select database() ##查看当前数据库、用户、时间和版本
select user();
select now();
select version()select * from mysql.db WHERE db LIKE 'db_name';查看某数据库下账号
show grants for 'user'@'机器ip' ##查看用户权限
grant all privileges on *.* to test@'10.10.10.%' identified by 'test123' ##允许test用户远程从10.10.10上连接。
grant all privileges on test.* to test@localhost ##授予全部权限
show variables like 'port';##查看mysql实例的端口。
select @@version; ##查询当前mysql的版本.
show variables like 'socket';##查看实例的socket数据。
show variables like 'datadir';##查看实例的数据路径。
explain ##查看语句的执行计划。
show index from table_name ##查看表的索引情况
select @@max_allowed_packet; ## 查询定义的packet大小
show master logs;##查看所有的log文件,在主服务器上执行。(即查看所有binlog日志列表)
purge binary logs to 'mysql-bin3306.000003'; #mysql-bin3306.000003之前的日志被purge
show warnings; ##显示最近的警告详情。
show variables \G; ##查看当前mysqld的所有参数,包括默认值。
show grants for 'username'@'hostip' \G; ##查看某一个用户的权限,请替换参数username 和 hostip
show variables like 'innodb_page_size'; ##查询页的大小。一旦数据库通过innodb_page_size设置完成,则后续无法更改。innodb_page_size是针对普通表的,压缩表不受限制。
show variables like 'innodb_buffer_pool_size';##查看缓冲池的大小,每次读写数据都是通过buffer pool;当buffer pool中没有所需的数据时,才去硬盘中获取。该值设置的越大越好。buffer pool 也是以页(page)为单位的,且大小和innodb_page_size一致。
show variables like 'innodb_buffer_pool_instances'; ##设置多少个缓冲池。设置多个instance可将热点打散,提高并发性能(建议设置成cpu个数值)
show engine innodb status \G;##查看buffer pool的状态。(查看默认存储引擎的类型: SELECT @@default_storage_engine;)
set global innodb_buffer_pool_size=2*1024*1024*1024;##在线调整innodb_buffer_pool_size。MySQL 5.7之前的版本,修改该值,需要重启。
show variables like 'innodb_buffer_pool_dump_at_shutdown'; ##在MySQL 5.6 以后,可以在停机的时候dump出buffer pool的数据,然后在启动的时候Load进buffer pool。该功能可以在MySQL启动时自动预热,无需人工干预。
show variables like 'innodb_buffer_pool_dump_pct';##dumpd 百分比,是每个buffer pool文件,而不是整体。
show variables like 'innodb_buffer_pool_load_at_startup';## 启动时加载dump的文件,恢复到buffer pool中。dump的越多,启动的越慢。
show variables like "%innodb_flush_log_at_timeout%";##master thread 每秒刷新redo的buffer到logfile。5.7版本可以设置刷新间隔时间,默认是1秒。
show variables like 'binlog_format';##查看binlog的类型。statement 记录SQL语句;ROW 记录SQL语句操作的那些行(行的变化);mixed 混合statement 和 Row 格式(不推荐)
###查询进程:
SELECT * FROM sys.processlist
SHOW FULL PROCESSLIST
SELECT * FROM information_schema.processlist
SELECT * FROM sys.session
SELECT * FROM performance_schema.events_statements_current
show processlist \G;##显示正在执行的线程
kill thd_id ##杀死线程/进程
###查询在锁事务,如果有可杀掉(kill 线程ID)
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
##联合查询锁定的表的具体事务:
select trx_id,INNODB_TRX.trx_state,INNODB_TRX.trx_started,se.conn_id as processlist_id,trx_lock_memory_bytes,se.user,se.command,se.state,se.current_statement,se.last_statement from information_schema.INNODB_TRX as is,sys.session as se where is.trx_mysql_thread_id=se.conn_id;
select * from innodb_lock_waits;##查看锁的信息,在数据库sys下执行
show variables like 'transaction_isolation'; ##查看隔离级别
set transaction_isolation='read-committed'; ##设置隔离级别
##锁等待查询
select * from information_schema.innodb_lock_waits;
select * from information_schema.innodb_locks;
select * from information_schema.innodb_trx;
##mysql查看数据库大小
SELECT sum(DATA_LENGTH)+sum(INDEX_LENGTH) FROM information_schema.TABLES where TABLE_SCHEMA='数据库名';
##mysql表占用的空间
SELECT TABLE_NAME,DATA_LENGTH+INDEX_LENGTH,TABLE_ROWS FROM TABLES WHERE TABLE_SCHEMA='数据库名' AND TABLE_NAME='表名';
##查看表的最后mysql修改时间
select TABLE_NAME,UPDATE_TIME from INFORMATION_SCHEMA.tables where TABLE_SCHEMA='数据库名';
##查看当前的连接数
show status like 'Threads%'; ##其中,Threads_connected 表当前连接数,Threads_running 表当前的并发数
##查看最大连接数
show variables like '%max_connections%';
show variables like '%slave_parallel_workers%';##从数据库用来还原的并发线程数
##QPS (Query per second) (每秒查询量)查询
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Uptime';
select 42260778868/26924936 AS QPS from dual;
##TPS(Transaction per second) (每秒事务量,如果是InnoDB会显示,没有InnoDB就不会显示)查看
SHOW GLOBAL STATUS LIKE 'Com_commit';
SHOW GLOBAL STATUS LIKE 'Com_rollback';
SHOW GLOBAL STATUS LIKE 'Uptime';
select (1676595+1)/26925163 as TPS from dual;
##慢查询及日志查看
mysql> show variables like 'long%'; #以秒为单位 mysql> set long_query_time=1; #超过1秒即为慢查询
mysql> show variables like 'slow%'; #查看慢查询是否开启 | slow_query_log | ON | #是否打开日志记录 |
slow_query_log_file | /tmp/slow.log | #设置到什么位置 mysql> set global slow_query_log='ON'#打开日志记录
show variables like 'slow_query_log_file';## 查看慢查询日志的路径
show variables like 'long_query_time'; ##查看慢查询定义的阈值,单位是秒。记录的查询是大于该值,不包括该值
show variables like 'log_slow_slave_statements';##查看从服务器是否开启慢查询日志,ON代表开启
show variables like 'log_queries_not_using_indexes';##将没有使用索引的SQL语句记录到慢查询日志中
show variables like 'log_throttle_queries_not_using_indexes';##限制每分钟内,在慢查询日志中,记录没有使用索引的次数。避免日志快速增长。
show variables like 'log_output'; ##查看日志的输出格式(file或table)
show variables like 'log_timestamps';##查看日志的时间信息,UTC时间或者SYSTEM时间
show variables like 'innodb_log_file_size';##查询log文件大小
.show variables like 'innodb_print_all_deadlocks';##设置为ON,表示将死锁信息打印到err_log中。
show binlog events in 'mysql-bin.000008'; ##查看指定binlog中的内容
flush binary logs;#刷新日志,并且会产生一个新的日志文件
show variables like "binlog_rows_query_log_events";##设置为ON,可以在ROW格式下,看到SQL的信息
how variables like "binlog_cache_size";##binlog默认写入到binlog_cache中,系统默认是32K,当有一个大的事务时(几百兆),内存中显然放不下那么多binlog,所以会记录到磁盘上
show global status like 'binlog_cache_disk_use';##记录了使用临时文件写二进制日志的次数。注意:写日志本来就停满的,如果cache写不下,再写入磁盘,然后再写binlog,就是写入2次磁盘,会更慢。如果参数binlog_cache_disk_use次数很多,就要看一下binlog_cache_size设置是否太小,或者事务本身是否太大。
##查库及表
show databases; -- 显示数据库
show create database db1 -- 显式数据库创建语句
show create table tablename \G; ##查看某表的创建脚本
describe 表名; -- 查看表结构
show create table 表名; -- 查看见表命令
show index from 表名; -- 查看表包含的索引
show table status like '%表名部分字符%'; -- 查看当前表的状态
select * from STATISTICS where table_name='XXX'\G ##查看表的统计信息
show variables like "default%tmp%";查看创建的临时表的存储引擎类型。
##表重复查询
select email from user group by email having count(email) > 1; -- 查询重复的列
select * from user where email in (
select email from user group by email having count(u_email) > 1
); -- 查询重复数据列的行
##MHA查询
masterha_check_repl --conf=/etc/masterha/app1.conf ##检查整个集群的复制状况
masterha_check_ssh --conf=/etc/masterha/app1.conf ##检查MHA集群SSH配置。
masterha_check_status --conf=/etc/masterha/app1.conf ##检查MHA Manager的状态:如果正常,会显示"PING_OK",否则会显示"NOT_RUNNING" ,这代表MHA监控没有开启。
nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 & ###监控进程通过nohup管理,可以通过jobs查看后台进程。
show slave hosts;##在master节点上执行,查看Slave节点数据。
CHANGE MASTER TO MASTER_HOST='172.XXX.XXX.XXX',MASTER_USER='replname',MASTER_PASSWORD='pwd',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154; ##change master 示例
若在Slave机器上对数据库进行修改或者删除,会导致主从的不一致,需对Slave机器设置为read_only = 1 ,让Slave提供只读操作。
注意: read_only 仅仅对没有SUPER权限的用户有效(即 mysql.user表的Super_priv字段为Y),一般给App 的权限是不需要SUPER权限的。参数super_read_only 可以将有SUPER权限的用户也设置为只读,且该参数设置为ON 后, read_only 也跟着自动设置为ON。
show variables like "server_uuid";## 查看UUID。 GTID(G lobal T ransaction Id entifier) 全局事物ID。GTID = Server_UUID +
Transaction_ID 其中 Server_UUID 是全局唯一的,Transaction_ID 是自增的。
show variables like "%gtid%";##查看gtid相关数据及配置
##从服务器跳过一个错误的事务
stop slave; 关闭复制
set session gtid_next='4e659069-3cd8-11e5-9a49-001c4270714e:1'; #设置 gtid_next 为回放失败的gtid,在session里设置gtid_next,即跳过这个GTID
begin;
commit;执行一个空的事物,让回放失败的gtid对应到这个空的事物
SET SESSION GTID_NEXT = AUTOMATIC; #把gtid_next设置回来,还原gtid_next为automatic
start slave;开启复制
2.2.2 mysql之【删】:
drop database db1; -- 删除数据库
drop table if exists tab1 ##删除表
alter table `Persons` drop column `City`; ##删表字段
2.2.3 mysql之【改】:
1)更改数据库引擎:
更改方式1: 修改配置文件my.ini,将my-small.ini另存为my.ini,在[mysqld]后面添加default-storage-engine=InnoDB,重启服务,数据库默认的引擎修改为InnoDB;
更改方式2: 在建表的时候指定,如下这样:
create table mytbl(
id int primary key,
name varchar(<strong>50</strong>)
)type=MyISAM;
更改方式3: 建表后更改:alter table mytbl2 type = InnoDB;
验证:how create table table_name 查看修改后的引擎;
2)改表
rename table Deal to Deal_201801, Deal_2018 to Deal; ##重命名表
alter table tb1 engine=myisam; ##修改表的数据引擎
alter table Persons modify column `City` varchar(255) DEFAULT NULL comment 改表字段
3)该密码:
set password for root@localhost = password('123456');
##方式2
use mysql;
update user set password=password('123456') where user='root' and host='localhost';
flush privileges;
2.2.4 mysql之【增】:
##在线创建索引
ALTER TABLE tb_name ALGORITHM=inplace, LOCK=NONE, ADD INDEX IDX_VID_CID(vid,cid)
##创建库
create databse db1; -- 创建一个数据库,数据库名在linux下大小写敏感
create database db1 character set utf8; -- 创建并定义字符集
带有字符集的建库语句
create database shang default character set gbk collate gbk_chinese_ci;
create database shang default character set utf8 collate utf8_gereral_ci;
##创建表
create tabale tb1 (
id int not null,
name varchar(10)
); -- 创建一张表
create tabale tb1 (
id int not null,
name varchar(10)
)engine=MYISAM default charset=utf8;
##给表增加字段
alter table Persons add column `City` varchar(255) DEFAULT NULL;
##单行出入
insert into tablename set column1 = value1 , coumn2 = values2...;
##多行插入
insert into tablename (column1,column2...) values (value1,value2....);
insert into tablename (column1,column2...) values (value1,value2....),(value1,)
2.2.5 mysql之登录及安全
启动:
/etc/init.d/mysqld start 等效mysql_safe --user=mysql &
登录提示符修改 prompt \u@oldboy \r:\m:\s->
mysql -uroot -p’面膜’ -S /data/3306/mysql.sock ##多实例登录
mysql -uroot -p -h 127.0.0.1 -P3307 ##远程登录,这时不需要socket
set password=password(‘新密码’) ##修改密码,完成后flush privileges
关闭:
/etc/init.d/mysqld stop
mysqladmin -uroot -p’密码’ shutdown
不建议以下强制停止:
killall mysqld
pkill mysqld
killall -9 mysqld kill pid
安全:
删除无用的mysql库内的用户账号,删除默认存在的test数据库
可以删除root账号,新建一个超级账号代替root账号:
delete from mysql.user;
grant all privileges on . to system@‘localhost’ identified by system with grant option
mysql丢失恢复:
1) /etc/init.d/mysqld stop
2)mysqld_safe --skip-grant-tables --user=mysql & ##启动数据库,用mysql 无密码登录mysql数据库
多实例: mysqld_safe --default-file=/u01/data/3306/my.cnf --skip-grant-tables &
/u01/data/3306/mysql -S /u01/data/3306/mysql.sock
3) update mysql.user set password=password(‘root123’) where user=‘root123’ and host=‘localhost’ ##修改密码
然后 flush privileges;
4)mysqladmin -uroot -proot123 shutdown ##用mysqladmin 关闭数据库
多实例;mysqladmin -uroot -proot123 shutdown -S /etc/data/3306/mysql.sock
5) /etc/init.d/mysqld start
6)验证:mysql -uroot -p
多实例:mysql -uroot -p -S /u01/data/mysql.sock
2.2.6 其他命令
##数据库的登录与退出
mysql -u root -p -- 使用root身份登陆当前的数据库
mysql -u root -p -h server0 -- 使用root身份登陆到server0的数据库
quit --退出数据库
## 数据库用户权限配置
grant privileges on db1.tablename to user1@10.168.0.8 identified by "password"; -- 按数据库授所有权限
grant select,insert,update,delete,create temporary tables,execute,show view on `db1`.* to 'user1'@'10.168.0.8'; -- 按数据库授特定权限
revoke select,insert,update,delete,create temporary tables,execute,show view on `db1`.* from 'user1'@'10.168.0.8'; -- 按数据库取消特定权限
drop user 'user1'@'10.168.0.8'; -- 删除特定的用户
fluse privileges; -- 刷新权限表
###用户得权限都有:
SELECT、 insert、UPDATE、DELETE、CREATE、DROP、REFERENCES、INDEX;
ALTER、CREATE TEMPORARY TABLES、LOCK TABLES、EXECUTE;
CREATE VIEW、SHOW VIEW、 CREATE ROUTINE、ALTER ROUTINE、EVENT、TRIGGER(触发 )
2.2.7 系统类执行的数据库相关命令
##数据库备份
mysqldump -u username -p database > /backup/file.dump -- 备份数据库
mysqldump -uroot -p --all-databases | gzip -9 > file.gz -- 备份并压缩数据库
mysqldump -u username -p <./file.dump -- 还原数据库
mysqldump重要参数 --all-databases :备份所有的数据库;--databases DB1 [DB2 DB3] :备份指定的数据库;--single-transaction : 在一个事物中导出,确保产生一致性的备份,当前只对innodb支持;--master-data : 备份的时候dump出CHANGE MASTER 信息(file 和 pos),可供主从复制的时候使用, 默认值为1,当值设置为2 的时候,也会dump出信息,但是会被注释掉 。
参数说明:
-B:指定数据库
-F:刷新日志
-R:备份存储过程等
由于上面在全备份的时候使用了-F选项,那么当数据备份操作刚开始的时候系统就会自动刷新log,这样就会自动产生一个新的binlog日志,这个新的binlog日志就会用来记录备份之后的数据库“增删改”操作
#改密码
mysqladmin -uroot -p password "123456"
2.3、概念篇
2.3.1 Mysql数据库引擎
【概念】:
数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎可控制访问权限并快速处理事务,从而满足企业内大多数需要处理大量数据的应用程序的要求。 使用数据库引擎创建用于联机事务处理或联机分析处理数据的关系数据库。这包括创建用于存储数据的表和用于查看、管理和保护数据安全的数据库对象(如索引、视图和存储过程)。
【引擎类别】:
可用的数据库引擎取决于mysql在安装的时候是如何被编译的。要添加一个新的引擎,就必须重新编译MYSQL。在缺省情况下,MYSQL支持三个引擎:ISAM、MYISAM和HEAP。另外两种类型INNODB和BERKLEY(伯克利BDB),常常使用。
ISAM:ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,MYSQL能够支持这样的备份应用程序。
MYISAM:MYISAM是MYSQL的ISAM扩展格式和缺省的数据库引擎。除了提供ISAM里所没有的索引和字段管理的功能,MYISAM还使用一种表格锁定的机制,来优化多个并发的读写操作。其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MYISAM还有一些有用的扩展,例如用来修复数据库文件的MYISAMCHK工具和用来恢复浪费空间的MYISAMPACK工具。 MYISAM强调了快速读取操作,这可能就是为什么MYSQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。
HEAP:HEAP允许只驻留在内存里的临时表格。驻留在内存里让HEAP要比ISAM和MYISAM都快,但是它所管理的数据是不稳定的,而且如果在关机之前没有进行保存,那么所有的数据都会丢失。在数据行被删除的时候,HEAP也不会浪费大量的空间。HEAP表格在你需要使用SELECT表达式来选择和操控数据的时候非常有用。要记住,在用完表格之后就删除表格。
INNODB和BERKLEYDB:INNODB和BERKLEYDB(BDB)数据库引擎都是造就MYSQL灵活性的技术的直接产品,这项技术就是MYSQL++ API。在使用MYSQL的时候,你所面对的每一个挑战几乎都源于ISAM和MYISAM数据库引擎不支持事务处理也不支持外来键。尽管要比ISAM和MYISAM引擎慢很多,但是INNODB和BDB包括了对事务处理和外来键的支持,这两点都是前两个引擎所没有的。
Innodb引擎:Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这篇文章。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
【名词解析:】
1)ACID
A 事务的原子性(Atomicity):指一个事务要么全部执行,要么不执行.也就是说一个事务不可能只执行了一半就停止了.比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱.不可能划了卡,而钱却没出来.这两步必须同时完成.要么就不完成.
C 事务的一致性(Consistency): 指事务的运行并不改变数据库中数据的一致性.例如,完整性约束了a+b=10,一个事务改变了a,那么b也应该随之改变.
I 独立性(Isolation):事务的独立性也有称作隔离性,是指两个以上的事务不会出现交错执行的状态.因为这样可能会导致数据不一致.
D 持久性(Durability):事务的持久性是指事务执行成功以后,该事务所对数据库所作的更改便是持久的保存在数据库之中,不会无缘无故的回滚.两者区别:
第一个重大区别是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
上图是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。例如,下图为定义在Col3上的一个辅助索引:
这里以英文字符的ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调(可能是指“非递增”的意思)的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调(可能是指“非递增”的意思)的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
2.3.2 Mysql两个文件(mysqld_safe与mysqld)区别
mysqld_safe与mysqld区别,直接运行mysqld程序来启动MySQL服务的方法很少见,mysqld_safe脚本会在启动MySQL服务器后继续监控其运行情况,并在其死机时重新启动它。
用mysqld_safe脚本来启动MySQL服务器的做法在BSD风格的unix系统上很常见,非BSD风格的UNIX系统中的 mysql.server脚本其实也是调用mysqld_safe脚本去启动MySQL服务器的。
它通常做如下事情:
- 检查系统和选项。
- 检查MyISAM表。
- 保持MySQL服务器窗口。
- 启动并监视mysqld,如果因错误终止则重启。
- 将mysqld的错误消息发送到数据目录中的host_name.err 文件。
- 将mysqld_safe的屏幕输出发送到数据目录中的host_name.safe文件。
【mysqld】:是mysql的核心程序,用于管理mysql的数据库文件以及用户的请求操作。mysqld可以读取配置文件中的[mysqld]的部分。
mysqld启动命令: /bin/mysqld --defaults-file=/etc/mysql/my.cnf &
【mysqld_safe】:相当于多了一个守护进程,mysqld挂了会自动把mysqld进程拉起来
1.可以读取的配置部分[mysqld],[server],[myslqd_safe], 为了兼容mysql_safe也会读取[safe_mysqld]中的配置
2.调用的mysqld是可以在[mysqld_safe]中用-mysqld, --mysqld-version指定
mysqld_safe启动命令:/bin/mysqld_safe --defaluts-file=/etc/mysql/my.cnf &
在Unix和NetWare中推荐使用mysqld_safe来启动mysqld服务器。
mysqld_safe增加了一些安全特性,例如当出现错误时重启服务器并向错误日志文件写入运行时间信息。
注释:为了保持同旧版本MySQL的向后兼容性,MySQL二进制分发版仍然包括safe_mysqld作为mysqld_safe的符号链接。但是,你不应再依赖它,因为再将来将删掉它。
默认情况下,mysqld_safe尝试启动可执行mysqld-max(如果存在),否则启动mysqld。该行为的含义是:
· 在Linux中,MySQL-Max RPM依赖该mysqld_safe的行为。RPM安装可执行mysqld-max,使mysqld_safe从该点起自动使用可执行命令。
· 如果你安装包括mysqld-max服务器的MySQL-Max分发版,后面升级到非-Max的MySQL版本,mysqld_safe仍然试图运行旧的 mysqld-max服务器。升级时,你应手动删除旧的mysqld-max服务器以确保mysqld_safe运行新的mysqld服务器。
要想越过默认行为并显式指定你想要运行哪个服务器,为mysqld_safe指定 --mysqld 或 --mysqld-version 选项。
mysqld_safe期望下面的其中一个条件是真的:
1)可以根据调用mysqld_safe的目录找到服务器和数据库。在二进制分发版中,mysqld_safe看上去在bin和data目录的工作目录下。对于源码分发版,为libexec和var目录。如果你从MySQL安装目录执行mysqld_safe应满足该条件(例如,二进制分发版为/usr/local/mysql)。
2)如果不能根据工作目录找到服务器和数据库,mysqld_safe试图通过绝对路径对它们定位。典型位置为/usr/local/libexec和 /usr/local/var。实际位置由构建分发版时配置的值确定如果MySQL安装到配置时指定的位置,它们应该是正确的。
mysqld_safe试图通过工作目录找到服务器和数据库,只要你从MySQL安装目录运行mysqld_safe,可以将MySQL二进制分发版安装到其它位置,启动时从安装位置来启动该脚本,如果mysqld_safe失败,即使从MySQL安装目录调用仍然失败,你可以指定–ledir和–datadir选项来指示服务器和数据库在你的系统中的安装目录。
一般情况,你不应编辑mysqld_safe脚本。相反,应使用命令行选项或my.cnf选项文件的[mysqld_safe]部分的选项来配置mysqld_safe。一般不需要编mysqld_safe来正确启动服务器。
2.4、调优篇
2.4.1、Mysql binlog日志过大配置有效时长
背景:在Mysql主从场景中,master开启了binlog日志,用于记录了数据库的操作日志和MySQL数据库的主从同步或者数据恢复。然随时间积累,大量的binlog日志会占用许多磁盘空间;导致MySQL因磁盘空间不足而一直告警,甚至导致服务无法访问。
[mysqld]
max_binlog_size = 500M
expire_logs_days = 15 #保留指定日期范围内(15天)的bin log历史日志
# mysql8.0以下版本查看当前数据库日志binlog保存时效 以天为单位,默认0,即永不过期,最多只能设置99天
show variables like 'expire_logs_days'; #默认为0,现场版本为5.7.34
set global expire_logs_days=60;
#mysql8.0以上版本通过设置全局参数binlog_expire_logs_seconds修改binlog保存时间 以秒为单位;默认2592000 30天 14400 4小时;86400 1天;259200 3天
show variables like '%binlog_expire_logs_seconds%';
set global binlog_expire_logs_seconds=259200;
#查看binlog列表
mysql> show binary logs;
mysql> show variables like 'max_binlog_size'; #单位byte
mysql> set global expire_logs_days=7;
mysql> purge master logs to 'master-bin.000007';
mysql> flush logs; //注意若 binlog非常多,不要轻易执行,可能导致IO争抢,建议使用purge命令予以清除
mysql> purge binary logs before '20yy-yy-yy yy:00:00';
mysql> show binary logs; #验证
mysql> show binlog events in 'master-bin.000002'; #查看指定binlog文件的内容
mysql> show binlog events; #只查看第一个binlog文件的内容