# ls /usr/local/mysql/bin mysql mysqladmin mysqldump 客户端程序 mysqld mysqld_safe 服务器端程序 mysqlcheck 非客户端程序 客户端程序: 需要连接到服务器端才能运行的程序,连接方式(TCP/IP、IPC) 服务器端程序: mysqld: mysqld_safe :单实例环境下安全的mysql线程 mysqld_multi:一个MySQL服务器可以启动多个服务,比如一个监听3306,另一个监听3307。这只在特殊场景下才会用到。 非客户端程序: mysqlcheck :不需要连接到服务器端执行的程序 MySQL服务器(mysqld,二进制安装方式)启动时读取配置文件的顺序: # mysqld --verbose --help | grep -C 5 my.cnf /etc/my.cnf => /etc/mysql/my.cnf => /usr/local/mysql/etc/my.cnf ~/.my.cnf # mysqld --print-defaults 打印详细的配置信息,也就是my.cnf中mysqld段的配置信息。 这里凡是以“--”开头的配置,都可以在启动mysqld时手动指定,比如: # runuser -s /bin/bash mysql -c '/usr/local/mysql/bin/mysqld --server-id=2' 剩余的不是以"--"开头的选项配置,有的可以在运行过程中修改,有些不可以。而且有些不能写入my.cnf配置文件,因为他们不是变量 MySQL的配置文件my.cnf属于多段配置,每段信息包含了对应程序的默认配置,比如有如下配置段: [mysqld] [mysqld_safe] [mysqldump] [client]
当我们设定表的某一个字段的长度为3,而我们却插入了10个字符进去,这时,我们也会执行成功,你知道吗?
MySQL的sql_mode(sql模型)就是用来设定服务器的工作模型的。起作用如下:
(1)可以兼容更多风格的mysql客户端,比如oracle管理员可以使用oracle操作习惯操作MySQL。
(2)可以限定MySQL的工作模式,比如严格模式、传统模式、宽松模式。
Sql_mode值 | 描述 |
ANSI | 更改语法和行为,使其更符合标准SQL。 |
STRICT_TRANS_TABLES | 如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。本节后面给出了更详细的描述。 |
TRADITIONAL | Make MySQL的行为象“传统”SQL数据库系统。该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。注释:一旦发现错误立即放弃INSERT/UPDATE。如果你使用非事务存储引擎,这种方式不是你想要的,因为出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。 |
下面以空的宽松模式演示: mysql> SHOW VARIABLES LIKE 'sql_mode'; 默认为空白,表示宽松模式 +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sql_mode | | +---------------+-------+ mysql> CREATE TABLE WOW(ID TINYINT,name CHAR(3)); mysql> INSERT INTO WOW VALUES (1,"tom"),(2,"jerry"); Query OK, 2 rows affected, 1 warning (0.01 sec) Records: 2 Duplicates: 0 Warnings: 1 未报错,只是给了警告 mysql> SHOW WARNINGS; mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1265 Message: Data truncated(截断) for column 'name' at row 2 mysql> SET sql_mode='strict_all_tables'; 修改为严格模式 mysql> INSERT INTO WOW VALUES (5,"wangyu"); ERROR 1406 (22001): Data too long for column 'name' at row 1 直接报错
查看和修改MySQL变量:
mysql> SHOW {GLOBAL|SESSION} VARIABLES LIKE 'var_name'; var_name大小写无所谓 mysql> SHOW {GLOBAL|SESSION} STATUS 静态修改变量: datadir = /mydata/data 动态修改变量: mysql> SET {GLOBAL|SESSION} variable_name='value'; 修改全局配置,对当前会话无效,只对新的会话有效 修改会话配置,对当前会话有效,对全局配置无效。 动态修改: GLOBAL:对当前会话无效,只对新建立的会话有效; SESSION:仅对当前会话有效; mysql> SHOW VARIABLES LIKE '%engine%'; +---------------------------+--------+ | Variable_name | Value | +---------------------------+--------+ | default_storage_engine | InnoDB | | engine_condition_pushdown | ON | | storage_engine | InnoDB | +---------------------------+--------+
MySQL的存储引擎:
MyISAM:只支持表级锁,
InnoDB:支持到行级锁,并发性提高,但是维护成本也提高
查看存储引擎:
mysql> SHOW ENGINES; 查看MySQL支持的存储引擎。 mysql> SHOW VARIABLES LIKE '%default_storage_engine%'\G 查看默认的 *************************** 1. row *************************** Variable_name: default_storage_engine Value: InnoDB mysql> SHOW TABLE STATUS LIKE ‘table_name’\G *************************** 1. row *************************** Name: WOW Engine: InnoDB 查看表的存储引擎
MySQL加锁方式:
显示锁: 手动明确加锁,比如在备份的时候 LOCK TABLES table_name1,table_name2,... {READ|WRITE}; UNLOCK TABLES; 手动解锁 隐式锁: 在执行select等语句时自动加的锁
更改MySQL的存储引擎:
mysql> use yy; mysql> SHOW TABLE STATUS LIKE 'WOW'\G *************************** 1. row *************************** Name: WOW Engine: InnoDB # mysqldump -uroot -p --database yy > /tmp/yy.sql mysql> DROP TABLE user; # sed -i 's/ENGINE=InnoDB/ENGINE=MyISAM/g' /tmp/yy.sql # mysql -uroot -p < /tmp/yy.sql mysql> show table status\G *************************** 1. row *************************** Name: WOW Engine: MyISAM
InnoDB事务演示:
MySQL的事务内置变量autocommit默认为ON,表示只要你写入的SQL语句一回车且能正确执行,这个事务就会自动提交到事务日志中。也就是MySQL会把每个SQL都当做一个事务。所以每次都会产生I/O,这就影响了性能。所以建议关闭。(对于MyISAM无效)
注意:这里指的是把每个SQL当做一个事务执行,才会影响性能。而不是每次提交事务才会影响性能。
START TRANSACTION 手动启动事务 SAVEPOINT point_name 手动保存一个回滚点,使得可以rollback此状态 ROLLBACK [TO point_name] 提交之前手动回滚,如果没有跟回滚点就会回滚到最开始的状态 COMMIT 手动提交事务
下面是手动开始一个事务:
记得将上面的存储引擎更改回来! mysql> SHOW VARIABLES LIKE 'autocommit'\G *************************** 1. row *************************** Variable_name: autocommit Value: ON mysql> SET autocommit=OFF; mysql> START TRANSACTION; mysql> use yy; mysql> SELECT * FROM user; +------+------+ | ID | NAME | +------+------+ | 1 | y1 | | 2 | y2 | | 3 | y3 | +------+------+ mysql> DELETE FROM user WHERE ID=1; mysql> SAVEPOINT del1; mysql> SELECT * FROM user; +------+------+ | ID | NAME | +------+------+ | 2 | y2 | | 3 | y3 | +------+------+ mysql> DELETE FROM user WHERE ID=2; mysql> SAVEPOINT del2; mysql> SELECT * FROM user; +------+------+ | ID | NAME | +------+------+ | 3 | y3 | +------+------+ mysql> ROLLBACK TO del1; mysql> SELECT * FROM user;这样就回滚到只删除ID=1的状态了。 +------+------+ | ID | NAME | +------+------+ | 2 | y2 | | 3 | y3 | +------+------+ mysql> COMMIT;
RDBMS的事务隔离级别:
READ-UNCOMMITTED 读未提交 比如有A&B两个会话,同时操作同一个表yy.user,那么A会话做的所有操作,在提交前, B会话都可以实时的看到。如果A总是需要ROOLBACK,那么就会对B会话产生严重干扰。 比如而B在已经确认tom用户是存在的,并且准备修改其ID号,但是就B回车前A删除了tom, 那么B的所有操作就是无效的。这就是幻读。 下面开启A&B会话,然后同时进行以下步骤: mysql> SET autocommit=OFF; mysql> SET tx_isolation='READ-UNCOMMITTED'; mysql> use yy; mysql> select * from user; +------+------+ | ID | NAME | +------+------+ | 1 | tom | | 2 | jar | | 3 | app | +------+------+ mysql> DELETE FROM user WHERE ID=1; mysql> insert into user values(4,"web"); 这里未提交 B会话: mysql> SELECT * FROM user; 这里立刻就可以看到A未提交的事务 +------+------+ | ID | NAME | +------+------+ | 2 | jar | | 3 | app | | 4 | web | +------+------+
READ-COMMITED 读提交 这是SQL server等数据库的默认级别。只有A会话提交事务(commit)以后, B会话才能看到A会话修改的内容。 依然会产生幻读,因为自己修改过的数据,可能由于其他事务的提交而导致在自己的事务内操作失败 。
REPEATABLE-READ 可重读 MySQL默认的隔离级别 采用MVCC机制,使得会话在自己的事务内,看到的表永远是一样的, 不会受到其他会话的事务提交或未提交造成的影响。 但是提交的后的结果就不是此事务能解决的了,所以依然会有幻读。 MVCC机制:多版本并发控制,每个事务启动后,都会对当前数据库的数据做一个快照。 此事务只能看到快照内的东西。
SERIALIZABLE 可串行化 当事务A占用一个资源时,事务B再访问时,就必须等待。这回极大的降低服务器性能。