mysql小知识点

参考:https://www.cnblogs.com/geaozhang/p/6834780.html

一、mysql选项查看,要会看这张表:

https://dev.mysql.com/doc/refman/5.7/en/server-option-variable-reference.html

https://mariadb.com/kb/en/library/full-list-of-mariadb-options-system-and-status-variables/

mysqld选项:

选项名称;是否可以作为命令行选项;是否可以作为为配置文件选项;是否是系统变量,是否为状态变量;变量的作用范围(有global和session两种);是否是动态参数

以sql-mode为例,它是命令行选项,又是文件选项,又是系统变量,变量作用范围为全局,动态:

sql-mode Yes Yes Yes Both Yes

1、sql-mode可以在运行mysqld时指定,下面指定seq-mode为空

[root@localhost ~]# /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock --sql-mode=''
#可以在mysql中看到其值为空
mysql> SELECT @@sql_mode;
+------------+
| @@sql_mode |
+------------+
|            |
+------------+
1 row in set (0.00 sec)

2、可以作为文件选项,可以在mysql的配置文件my.cnf的mysqld段指定

[root@localhost ~]# vim /etc/my.cnf
[mysqld]
sql-mode='ONLY_FULL_GROUP_BY'
...
[root@localhost ~]# systemctl restart mysqld
mysql> SELECT @@sql_mode;
+--------------------+
| @@sql_mode         |
+--------------------+
| ONLY_FULL_GROUP_BY |
+--------------------+
1 row in set (0.00 sec)

3、sql-mode是系统变量,系统变量可以使用show variables查看,也可以通过set global设置

#服务器系统变量分为全局变量和会话变量两种
#获取系统变量有三种命令
mysql> SHOW VARIABLES LIKE 'sql_mode';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| sql_mode      | ONLY_FULL_GROUP_BY |
+---------------+--------------------+
1 row in set (0.01 sec)
mysql> select @@sql_mode;
+--------------------+
| @@sql_mode         |
+--------------------+
| ONLY_FULL_GROUP_BY |
+--------------------+
1 row in set (0.00 sec)
mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)
#修改全局变量,两种命令
mysql> set @@global.sql_mode='';
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL sql_mode='';
Query OK, 0 rows affected (0.00 sec)
#查看会话变量
mysql> SHOW SESSION VARIABLES;
#修改会话变量两种方式
SET @@session.system_var_name=value;
SET SESSION system_var_name=value;

4、sql_mode不是状态变量,因此查不到

#服务器状态变量分为全局和会话两种,状态变量只读
mysql> SHOW GLOBAL STATUS;
mysql> SHOW SESSION STATUS;
mysql> SHOW GLOBAL STATUS LIKE 'sql_mode';
Empty set (0.00 sec)

5、sql-mode该变量的范围是global和session,可以分别查看下

#全局变量下sql_mode为空是我上面使用SET GLOBAL sql_mode='';设置的
mysql> SHOW GLOBAL VARIABLES LIKE 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)

mysql> SHOW SESSION VARIABLES LIKE 'sql_mode';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| sql_mode      | ONLY_FULL_GROUP_BY |
+---------------+--------------------+
1 row in set (0.00 sec)

6、sql_mode是动态参数

二、sql_mode的含义

​ 对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置

​ 参考:https://mariadb.com/kb/en/library/sql-mode/

比如: ONLY_FULL_GROUP_BY

​ 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的。

三、mysqladmin检测mysql状态

mysqladmin可以修改密码,删除,创建数据库,刷新表,刷新日志,查看状态,关闭数据库

[root@localhost support-files]# mysqladmin -uroot -p ping 
Enter password: 
mysqld is alive
[root@localhost support-files]# mysqladmin -uroot -p status
Enter password: 
Uptime: 6295  Threads: 1  Questions: 57  Slow queries: 0  Opens: 109  Flush tables: 1  Open tables: 102  Queries per second avg: 0.00

四、mysql忘记密码

网上文章还是挺多的!!!

https://dev.mysql.com/doc/refman/5.7/en/server-option-variable-reference.html

从上面链接的表上可以看到,skip-grant-tables变量可以作为命令行选项用,也可以当配置文件选项来使用

skip-grant-tables Yes Yes

在命令行中使用:

关闭数据库,以--skip-grant-tables启动mysqld
[root@localhost ~]# /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --skip-grant-tables &
[root@localhost ~]# mysql -uroot -p
Enter password: 
mysql> UPDATE mysql.user SET authentication_string=password('123456789') WHERE user='root' AND host='localhost';
mysql> FLUSH PRIVILEGES;
mysql> QUIT
[root@localhost ~]# pkill mysql
[root@localhost ~]# systemctl start mysql

在配置文件中使用

#my.cnf加一行或两行都加上
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
skip-grant-tables
skip-networking
[root@localhost ~]# systemctl restart mysql
[root@localhost ~]# mysql -uroot -p
Enter password: 
mysql> UPDATE mysql.user SET authentication_string=password('123456') WHERE user='root' AND host='localhost';
mysql> FLUSH PRIVILEGES;
mysql> QUIT
#删掉my.cnf中的那两行,重启mysql
[root@localhost ~]# vim /etc/my.cnf
[root@localhost ~]# systemctl restart mysql

五、mysql的3306端口抓包实验

通过wireshark抓包,看到将mysql的数据包全部截获,并且全部是明文,mysql加密后的密码也截获到,mysql的密码加密机器简单,通过在线解密工具很容易得到其真实密码,这就是为何mysql的3306端口坚决不能暴露的原因。还有就是mysql一般监听在本地或者局域网内,公网的话如果必须要,那么一定要设置防火墙,安全组。

六、mysql怎么允许别的主机连

首先selinux和防火墙关掉或者设置规则
然后mysql的my.cnf要设置监听在所有地址上:bind-address=*,并重启mysql
接着mysql对其授权:mysql> GRANT ALL ON wordpress.* TO 'tom'@'192.168.38.%' IDENTIFIED BY '123456';
接着刷新权限:mysql> FLUSH PRIVILEGES;
不出意外就可以了:[root@web ~]# mysql -utom -p -h192.168.38.132

七、mysql备份还原注意

写好备份脚本后,一定要手动备份一次,看能否成功,并且将备份的数据库文件在测试机上做还原演练,看备份的对不对,能不能用

八、mysql的索引

索引的查看,添加,删除,以及explain查询是否使用了索引

查看表上的索引:

mysql> DESC students;		#主键也是索引,索引分好多种
mysql> SHOW INDEX FROM hellodb.students;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| students |          0 | PRIMARY  |            1 | StuID       | A         |          25 |     NULL | NULL   |      | BTREE      |         |               |
| students |          1 | idx_name |            1 | Name        | A         |          25 |     NULL | NULL   |      | BTREE      |         |               |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

添加索引:

mysql> CREATE INDEX idx_name ON students(name);

如何确认查询使用了索引:

mysql> explain select * from students where stuid=16;
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table    | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | students | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+----------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

删除索引:

mysql> DROP INDEX idx_name ON students;

九、myisam和innodb区别

我记得最深刻的一点就是myisam是表级锁,而innodb支持行级锁。好处就是不至于我改表上内容,别人完全无法修改此表

然后:Myisam不支持事务,不支持事务就比较难受了,innode支持

Myisam不支持热备,innode支持

(明天补充)

十、索引不是必须有

常用的索引类型是B tree,有助于读请求,但不利于写请求。

十一、事务的四个特性

参考:https://www.cnblogs.com/geaozhang/p/10478918.html

看到事务,让我联想到银行取钱,不会因为银行突然断电,钱取出来了钱没扣

ACID

A:原子性:一个事务中的操作要么都成功,要么都失败回滚

C:一致性:在整个事务的生命周期里面,查询到的数据是一致的;

I:隔离性:隔离级别;

D:持久性: 只要事务commit,这个事务不会因为系统的崩溃而丢失;

十二、MySQL默认每一条SQL都是一条事务

意思是:我这个命令只要回车了,立马会执行

mysql> SHOW VARIABLES LIKE '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)

有DBA工程师说,关闭SQL的自动提交,避免误操作

十三、事务的隔离级别

1234

十四、mysqldump --single-transaction参数的作用

--single-transaction参数的作用,设置事务的隔离级别为可重复读,即REPEATABLE READ,这样能保证在一个事务中所有相同的查询读取到同样的数据,也就大概保证了在dump期间,如果其他innodb引擎的线程修改了表的数据并提交,对该dump线程的数据并无影响,在这期间不会锁表。

十五、my_print_defaults

my_print_defaults 这个程序是用来解析my.cnf文件的,将其中的参数打印到终端。这个小程序在mysql的启动脚本中会有用到。

[root@localhost ~]# my_print_defaults --defaults-file=/etc/my.cnf client 
--socket=/var/lib/mysql/mysql.sock
--port=3306
[root@localhost ~]# my_print_defaults --defaults-file=/etc/my.cnf mysqld
--server-id=2
--gtid-mode=on
--enforce_gtid_consistency=on
--datadir=/data/mysql
--socket=/var/lib/mysql/mysql.sock
--symbolic-links=0
--log-error=/var/log/mysqld.log
--pid-file=/var/run/mysqld/mysqld.pid

十六、binlog相关命令

#mysql外面看binlog,可以指定某一范围
[root@localhost ~]# mysqlbinlog -vvv /data/mysql/mysql-bin.000008 
#mysql里面看binlog名字和大小
mysql> show binary logs;
#mysql里面看当前的binlog文件名和position位置
mysql> show master status;
#slave查看同步状态
mysql> show slave status\G
#开启线程,第一次开启后,以后重启数据库会自启
mysql> show slave status\G
#slave停止线程
mysql> stop slave;
#删除指定日期前面的binlog
mysql> PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26';
sync_binlog=1 	#每次写后立即同步二进制日志到此磁盘,性能差
innodb_flush_log_at_trx_commit=1	#每次事务提交立即同步日志写磁盘

十七、DDL,DML

DDL:数据定义语言,管理数据库的对象(CREATE,DROP,ALTER,TRUNCATE)

DML:数据操纵语言:SELECT,INSERT,UPDATE,DELETE,CALL,EXPLAIN

十八、从数据库如果还想再连slave数据库

#slave开启binlog和更新master的binlog到自己
[mysqld]
log_bin
log_slave_updates

十九、压力测试、优化吞吐量

参考:https://blog.csdn.net/qq_18312025/article/details/78897023

二十、事务

事务(Transaction):组织多个操作为一个整体,要么全部都成功执行,要么失败回滚;
一个存储系统是否支持事务,测试标准:
	ACID:
		A:原子性;
		C:一致性;
		I:隔离性;
		D:持久性;