mysql优化和全局管理杂记

information_schema 系统元数据库

DESC information_schema.TABLES
TABLE_SCHEMA ---->库名
TABLE_NAME ---->表名
ENGINE ---->引擎
TABLE_ROWS ---->表的行数
AVG_ROW_LENGTH ---->表中行的平均行(字节)
INDEX_LENGTH ---->索引的占用空间大小(字节)

mysql 压测

mysqlslap --defaults-file=/etc/my.cnf
--concurrency=100 --iterations=1 --create-schema='dbname'
--query="select * from dbname.tablename where k2='mn80'" engine=innodb
--number-of-queries=2000 -uroot -pxxx -verbose

--concurrency 并发数量
--iterations 运行这些测试多少次
--number-of-queries 总共要运行多少次查询。每个客户运行的查询数量可以用查询总数/并发数来计算
-verbose 引用的配置

常用show 命令

show databases; #查看所有数据库
show tables; #查看当前库的所有表
SHOW TABLES FROM #查看某个指定库下的表
show create database world #查看建库语句
show create table world.city #查看建表语句
show grants for root@'localhost' #查看用户的权限信息
show charset; #查看字符集
show collation #查看校对规则
show processlist; #查看数据库连接情况
show index from #表的索引情况
show status #数据库状态查看
SHOW STATUS LIKE '%lock%'; #模糊查询数据库某些状态
SHOW VARIABLES #查看所有配置信息
SHOW variables LIKE '%lock%'; #查看部分配置信息
show engines #查看支持的所有的存储引擎
show engine innodb statusG #查看InnoDB引擎相关的状态信息
show binary logs #列举所有的二进制日志
show master status #查看数据库的日志位置信息
show binlog evnets in #查看二进制日志事件
show slave status G #查看从库状态
SHOW RELAYLOG EVENTS #查看从库relaylog事件信息
desc (show colums from city) #查看表的列定义信息

索引设计规范

(1) 必须要有主键,如果没有可以做为主键条件的列,创建无关列
(2) 经常做为where条件列 order by group by join on, distinct 的条件(业务:产品功能+用户行为)
(3) 最好使用唯一值多的列作为索引,如果索引列重复值较多,可以考虑使用联合索引
(4) 列值长度较长的索引列,我们建议使用前缀索引.
(5) 降低索引条目,一方面不要创建没用索引,不常使用的索引清理,percona toolkit(xxxxx)
(6) 索引维护要避开业务繁忙期

不会走索引的情况

(1)没有查询条件,或者查询条件没有建立索引
(2)查询结果集是原表中的大部分数据,应该是25%以上。
(3)索引本身失效,统计数据不真实
(4)查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等)
(5)隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误.
(6)<> ,not in 不走索引(辅助索引)
(7)like "%_" 百分号在最前面不走

联合索引

idx(k1,k2,k3)
1.在where条件中都是等值的 where k1=xx and k2=xx and k3=xx
无关where条件的顺序,只要把控建索引时,需要把唯一值较多的放在最左侧
2。在条件查询中没有最左列条件时,没有k1列的查询,都是不走索引的
意外情况:将表中的所有列建立联合,没有个列做查询条件都会走索引
3.如果查询中出现(> < >= <= like)
a= xx and b<xxx
建立索引时,等值条件放左边,不等值放最后
4.多子句时
where c xxx order by a,b
idx(c,a,b)

修改存储引擎

修改表为innodb

alter table t111 engine=innodb;
也可以整理碎片(常用)

批量替换zabbix 100张表,转innodb为tokudb

alter table zabbix.a engine=tokudb
select concat("alter table",table_schema,".",table_name," engine=tokudb;")
-->from information_schema.tables
-->where table_schema='zabbix'

innodb 单数据库迁移

其实就是独立表空间idb(tablesapace)迁移
1、按照原来建表语句,在新库中创建一个空的表
2、干掉新库的idb文件
-->alter table zabbix discard tablespace;
3、将原来表的idb 文件拷贝到数据目录下,修改权限
4、把idb重新导入进去
-->alter table zabbix import tablespace;

案例:底层磁盘块拷贝

坏盘/dev/sdb
新盘/dev/sdc
dd if=/dev/sdb of=/dev/sdc
断电后sdb盘损坏,将磁盘挂到正常系统,然后将里面的数据块整体对刻到新盘sdc,用于尝试修复、恢复数据。
1、从备份中拿到数据结构:mysqldump -uroot -pxxx -B zabbix --no-data >test.sql
通过数据结构sql新建所有表
2、跳过外检检查 set foreign_key_checks=0
3、discard 表空间删除:select concat('alter table ',table_schema,'.'table_name,' discard tablespace;')
from information_schema.tables
where table_schema='zabbix'
into outfile '/tmp/discad.sql'
执行 source /tmp/discard.sql
4、拷贝所有ibd数据库文件到新生成的库目录下
5、import 表空间导入:select concat('alter table ',table_schema,'.'table_name,' import tablespace;')
from information_schema.tables
where table_schema='zabbix'
into outfile '/tmp/import.sql
执行source /tmp/import.sql
6、测试数据

隔离级别

read-uncommit 允许脏读:还在内存中,并没有被确认提交、还没写入落盘的数据被读取——(解决)——>>修改事务完全提交后才允许写入
read-commit 不可重复读取:每次重复读的不一样,可被幻读,例如数据正在被写入,在写入操作执行完前和写入执行完之后读取的内容不一致——(解决)——>>修改事务完全提交后才允许读取
repeatable-read 可重复读:解决不可重复读,但可幻读;利用undo快照+锁,读到的一直是某一时刻的数据。
幻读:在批量对某个列数据修改过程中,有新的满足被修改条件的数据插入,导致新数据没有被修改。
在rr模式下 利用间隙锁和下键锁 这两把锁,配合索引避免幻读。

innodb配置优化部分

双1标准

sync_binlog=1 (每次失误提交都立即刷写到磁盘)
innodb_flush_log_at_trx_commit=1

=1 每次commit redo日志从mysql内存 立即提交 os_buffer 立即提交disk 最安全,但费io
=0 每次commit redo日志从mysql内存 1秒提交 os_buffer 1秒提交disk 可能掉1秒数据,但节约io性能
=2 每次commit redo日志从mysql内存 立即提交 os_buffer 1秒提交disk 一般不用
os_buffer 系统内存的意思

my.cnf配置

innodb_flush_method=o_direct
o_direct(最安全)|fsync(最性能)
redo buffer(日志):先写os_buffer 在到disk (ib_logfile1)
data buffer pool(数据):直接写到disk,不经过os_buffer
·····
innodb_max_dirty_pages_pct=75
最大脏页占用内存比例75,达到后刷到磁盘
.....
log_error=/tmp/xxx.log
指定错误日志存放位置,最好不和data数据放一起,避免数据丢
.....
server_id=6
log_bin=/data/binlog/mysql-bin
指定二进制日志

mkdir -p /app/
tar -zxvf mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.20-linux-glibc2.12-x86_64 mysql


cat >/etc/profile <<EOF
export PATH=/app/mysql/bin:$PATH
EOF

source /etc/profile

useradd mysql 

mkdir /data/mysql -p 
chown -R mysql.mysql /app/*
chown -R mysql.mysql /data/*

yum install -y libaio-devel

rm -rf /data/mysql/data/*
mysqld --initialize-insecure --user=mysql --basedir=/app/mysql  --datadir=/data/mysql/data
#mysqld --initialize  --user=mysql --basedir=/app/mysql --datadir=/data/mysql  或者
#》》.;epD(oUD2ku

cat >/etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=/app/mysql
datadir=/data/mysql/data
server_id=6
port=3306
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock
EOF


cp /app/mysql/support-files/mysql.server    /etc/init.d/mysqld
service mysqld restart
#cd /app/mysql/support-files
#./mysql.server start


cat >/etc/systemd/system/mysqld.service <<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/app/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000
EOF

大表删除

删除大表,先建ibd 的硬链接xxibd,然后再数据库中drop 表,速度非常块,然后安装truncate工具 分大小块删除xxibd,最后剩余块之后rm xxibd 即可。

原文地址:https://www.cnblogs.com/plefan/p/14333014.html