MYSQL慢查询日志分析
mysql有一个功能就是可以log下来运行的比较慢的sql语句,默认是没有这个log的,为了开启这个功能,要修改my.cnf或者在mysql启动的时候加入一些参数。如果在my.cnf里面修改,需增加如下几行
long_query_time = 10
log-slow-queries =
long_query_time 是指执行超过多久的sql会被log下来,这里是10秒。
log-slow-queries 设置把日志写在那里,为空的时候,系统会给慢查询日志赋予主机名,并被附加slow.log
如果设置了参数log-long-format,那么所有没有使用索引的查询也将被记录。在文件my.cnf或my.ini中加入下面这一行可以记录这些查询
这是一个有用的日志。它对于性能的影响不大(假设所有查询都很快),并且强调了那些最需要注意的查询(丢失了索引或索引没有得到最佳应用)
# Time: 070927 8:08:52
# User@Host: root[root] @ [192.168.0.20]
# Query_time: 372 Lock_time: 136 Rows_sent: 152 Rows_examined: 263630
select id, name from manager where id in (66,10135);
这是慢查询日志中的一条,用了372秒,锁了136秒,返回152行,一共查了263630行
如果日志内容很多,用眼睛一条一条去看会累死,mysql自带了分析的工具,使用方法如下:
命令行下,进入mysql/bin目录,输入mysqldumpslow –help或--help可以看到这个工具的参数,主要有
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]
Parse and summarize the MySQL slow query log. Options are
--verbose verbose
--debug debug
--help write this text to standard output
-v verbose
-d debug
-s ORDER what to sort by (t, at, l, al, r, ar etc), 'at' is default
-r reverse the sort order (largest last instead of first)
-t NUM just show the top n queries
-a don't abstract all numbers to N and strings to 'S'
-n NUM abstract numbers with at least n digits within names
-g PATTERN grep: only consider stmts that include this string
-h HOSTNAME hostname of db server for *-slow.log filename (can be wildcard),
default is '*', i.e. match all
-i NAME name of server instance (if using mysql.server startup scrīpt)
-l don't subtract lock time from total time
-s,是order的顺序,说明写的不够详细,俺用下来,包括看了代码,主要有
c,t,l,r和ac,at,al,ar,分别是按照query次数,时间,lock的时间和返回的记录数来排序,前面加了a的时倒叙
-t,是top n的意思,即为返回前面多少条的数据
-g,后边可以写一个正则匹配模式,大小写不敏感的
mysqldumpslow -s c -t 20 host-slow.log
mysqldumpslow -s r -t 20 host-slow.log
上述命令可以看出访问次数最多的20个sql语句和返回记录集最多的20个sql。
mysqldumpslow -t 10 -s t -g “left join” host-slow.log
这个是按照时间返回前10条里面含有左连接的sql语句。
一般cpu达到100%都是垃圾SQL和索引不当造成的。
只要硬盘有空余内存不是很小,就可以确定是SQL问题。
mount后做软链问题
好的,机器1:/data/archivedir /data/stardeals/log/admin机器2:/data1/archivedir
目地:想把机器1的/data/stardeals/log/admin里的log,同步到机器2的/data1/archivedir上
mount没有问题,
但是在机器1上执行ln -s /data/stardeals/log/admin /data/archivedir/adminlog
在机器1上正常
但是登录到机器2上时,adminlog这个link是不可以用的
求助,哈哈
MYSQL服务器系统变量
查询MYSQL服务器系统变量:C:\Program Files\MySQL\MySQL Server 5.0\bin> mysqld --verbose –help
通过mysqladmin命令来查询MYSQL服务器系统变量:
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysqladmin -uroot -p variables > d:\init.txt
Enter password: ******
Init.txt部分内容:
+---------------------------------+----------------------------------------------------------------+
| Variable_name | Value |
+---------------------------------+----------------------------------------------------------------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| automatic_sp_privileges | ON |
| back_log | 50
…………
| version_compile_machine | ia32 |
| version_compile_os | Win32 |
| wait_timeout | 28800 |
+---------------------------------+----------------------------------------------------------------+
获得MYSQL实际使用的服务器系统变量:
mysql> show variables;
利用like参数来显示具体的服务器系统变量:
mysql> show variables like 'init_connect%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| init_connect | |
+---------------+-------+
1 row in set (0.00 sec)
调整MYSQL服务器的系统变量
mysqld服务器维护两种变量。全局变量影响服务器的全局操作。会话变量影响具体客户端连接相关操作。服务器启动时,将所有全局变量初始化为默认值。可以在选项文件或命令行中指定的选项来更改这些默认值。服务器启动后,通过连接服务器并执行SET GLOBAL var_name语句可以更改动态全局变量。要想更改全局变量,必须具有SUPER权限。
方法一:
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 23068672 |
+------------------+----------+
1 row in set (0.01 sec)
mysql> SET GLOBAL query_cache_size = 31457280;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 31457280 |
+------------------+----------+
1 row in set (0.00 sec)
方法二:
mysql> show variables like 'query_cache_size%';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 31457280 |
+------------------+----------+
1 row in set (0.00 sec)
mysql> SET @@global.query_cache_size = 20971520;
Query OK, 0 rows affected (0.09 sec)
mysql> show variables like 'query_cache_size%';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| query_cache_size | 20971520 |
+------------------+----------+
1 row in set (0.00 sec)
mysql> select @@query_cache_size;
+--------------------+
| @@query_cache_size |
+--------------------+
| 20971520 |
+--------------------+
1 row in set (0.06 sec)
mysqld服务器还为每个客户端连接维护会话变量。连接时使用相应全局变量的当前值对客户端会话变量进行初始化。客户可以通过SET [SESSION] var_name语句来更改动态会话变量。设置会话变量不需要特殊权限,但客户可以只更改自己的会话变量,而不更改其它客户的会话变量。
mysql> SET sort_buffer_size = 10 * 1024 * 1024;
Query OK, 0 rows affected (0.08 sec)
mysql> show variables like 'sort_buffer%';
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| sort_buffer_size | 10485760 |
+------------------+----------+
1 row in set (0.00 sec)
注意:
当使用启动选项设置变量时,变量值可以使用后缀K、M或G分别表示千字节、兆字节或gigabytes。例如,下面的命令启动服务器时的键值缓冲区大小为16 megabytes:
C:\ProgramFiles\MySQL\MySQL Server 5.0\bin>mysqld--key_buffer_size=16M
后缀的大小写美关系;16M和16m是同样的。
运行时,使用SET语句来设置系统变量。此时,不能使用后缀,但值可以采取下列表达式:
mysql> SET sort_buffer_size = 10 * 1024 * 1024;
2 MYSQL服务器状态变量
mysqladmin查看服务器状态变量(动态变化):
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysqladmin -uroot -p extended-status
Enter password: ******
+-----------------------------------+----------+
| Variable_name | Value |
+-----------------------------------+----------+
| Aborted_clients | 0 |
| Aborted_connects | 3 |
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Bytes_received | 2664 |
| Bytes_sent | 96723 |
| Com_admin_commands | 0 |
| Com_alter_db | 0 |
| Com_alter_table | 0 |
| Com_analyze | 0 |
该命令和下面命令等效:
获得MYSQL服务器的统计和状态指标:
mysql> show status;
+-----------------------------------+----------+
| Variable_name | Value |
+-----------------------------------+----------+
| Aborted_clients | 0 |
| Aborted_connects | 3 |
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Bytes_received | 765 |
| Bytes_sent | 80349 |
| Com_admin_commands | 0 |
| Com_alter_db | 0 |
| Com_alter_table | 0 |
| Com_analyze | 0 |
刷新MYSQL服务器状态变量
mysql> show status like 'Bytes_sent%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent | 53052 |
+---------------+-------+
1 row in set (0.00 sec)
mysql> flush status;
Query OK, 0 rows affected (0.00 sec)
mysql> show status like 'Bytes_sent%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent | 11 |
+---------------+-------+
1 row in set (0.00 sec)
mysql 5.0 与 5.1 记录慢查询日志的区别
在mysql5.1之前的版本中,只需要log_slow_queries=filename // 注意:这里必须是绝对路径
slow-query-log=1
就可以开启Slow Query log(慢查询日志)了。
但这样在mysql 5.1中并不管用。
日志中会有如下的错误:
[Warning] '--log_slow_queries' is deprecated and will be removed in a future release. Please use ''--slow_query_log'/'--slow_query_log_file'' instead.
修改如下:
log_output=FILE # also can be FILE,TABLE or TABLE or NONE
slow-query-log=1
slow_query_log_file=filename
清除mysql庞大的binlog
环境:mysql master/slave架构问题:主库硬盘不足
原因:mysql的var下大量bin二进制log,200多个g啊
目标:安全删除binlog
方法:网上搜搜关键词“mysql bin文件 删除”,还真有~~
相关语句:
PURGE {MASTER | BINARY} LOGS TO 'log_name'
PURGE {MASTER | BINARY} LOGS BEFORE 'date'
用于删除列于在指定的日志或日期之前的日志索引中的所有二进制日志。这些日志也会从记录在日志索引文件中的清单中被删除,这样被给定的日志成为第一个。
例如:
PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
BEFORE变量的date自变量可以为'YYYY-MM-DD hh:mm:ss'格式。MASTER和BINARY是同义词。
如果您有一个活性的从属服务器,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起作用,而是会失败,并伴随一个错误。不过,如果从属服务器是休止的,并且您碰巧清理了其想要读取的日志之一,则从属服务器启动后不能复制。当从属服务器正在复制时,本语句可以安全运行。您不需要停止它们。
要清理日志,需按照以下步骤:
1. 在每个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪个日志。
2. 使用SHOW MASTER LOGS获得主服务器上的一系列日志。
3. 在所有的从属服务器中判定最早的日志。这个是目标日志。如果所有的从属服务器是更新的,这是清单上的最后一个日志。
4. 制作您将要删除的所有日志的备份。(这个步骤是自选的,但是建议采用。)
5. 清理所有的日志,但是不包括目标日志
实践:
从库下---
mysql> show slave status\G;
……
Master_Log_File: tc-ns-comment-db00-bin.000162
Relay_Master_Log_File: tc-ns-comment-db00-bin.000162
……
主库下---
mysql> show master log;
…………一堆堆
mysql> PURGE MASTER LOGS TO 'tc-ns-comment-db00-bin.000070';
……等待n长时间
mysql>quit
$du -sh ./
减少了好多g啊,世界清净了~~
总结:发现这个解决方法,其实就是mysql参考手册的原文cp,但是一个but,问题是不知道原来这个语句是用在这里的啊……汗一下自己
mysql中REPAIR TABLE 和 OPTIMIZE TABLE 的用途和区别
REPAIR TABLE `table_name` 修复表OPTIMIZE TABLE `table_name` 优化表
REPAIR TABLE 用于修复被破坏的表。
OPTIMIZE TABLE 用于回收闲置的数据库空间,
当表上的数据行被删除时,所占据的磁盘空间并没有立即被回收,使用了OPTIMIZE TABLE命令后这些空间将被回收,并且对磁盘上的数据行进行重排(注意:是磁盘上,而非数据库)。
多数时间并不需要运行OPTIMIZE TABLE,只需在批量删除数据行之后,或定期(每周一次或每月一次)进行一次数据表优化操作即可,只对那些特定的表运行。
mysql引擎性能简单测试
[硬件配置]CPU : AMD2500+ (1.8G)
内存: 1G/现代
硬盘: 80G/IDE
[软件配置]
OS : Windows XP SP2
SE : PHP5.2.1
DB : MySQL5.0.37
Web: IIS6
[MySQL表结构]
CREATE TABLE `myisam` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) default NULL,
`content` text,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
CREATE TABLE `innodb` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(100) default NULL,
`content` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
[数据内容]
$name = "heiyeluren";
$content = "MySQL支持数个存储引擎作为对不同表的类型的处理器。MySQL存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎:· MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默认的存储引擎,除非你配置 MySQL默认使用另 外一个引擎。 ·MEMORY存储引擎提供“内存中”表。MERGE存储引擎允许集合将被处理同样的MyISAM表作为一个单独的表。就像MyISAM一样,MEMORY和MERGE存储引擎处理非事务表,这两个引擎也都被默认包含在MySQL中。释:MEMORY存储引擎正式地被确定为HEAP引擎。· InnoDB和BDB存储引擎提供事务安全表。BDB被包含在为支持它的操作系统发布的MySQL-Max二进制分发版里。InnoDB也默认被包括在所有MySQL 5.1二进制分发版里,你可以按照喜好通过配置MySQL来允许或禁止任一引擎。·EXAMPLE存储引擎是一个“存根”引擎,它不做什么。你可以用这个引擎创建表,但没有数据被存储于其中或从其中检索。这个引擎的目的是服务,在MySQL源代码中的一个例子,它演示说明如何开始编写新存储引擎。同样,它的主要兴趣是对开发者。";
[插入数据-1] (innodb_flush_log_at_trx_commit=1)
MyISAM 1W:3/s
InnoDB 1W:219/s
MyISAM 10W:29/s
InnoDB 10W:2092/s
MyISAM 100W:287/s
InnoDB 100W:没敢测试
[插入数据-2] (innodb_flush_log_at_trx_commit=0)
MyISAM 1W:3/s
InnoDB 1W:3/s
MyISAM 10W:30/s
InnoDB 10W:29/s
MyISAM 100W:273/s
InnoDB 100W:423/s
[插入数据3] (innodb_buffer_pool_size=1024M)
InnoDB 1W:3/s
InnoDB 10W:33/s
InnoDB 100W:607/s
[插入数据4] (innodb_buffer_pool_size=256M, innodb_flush_log_at_trx_commit=1, set autocommit=0)
InnoDB 1W:3/s
InnoDB 10W:26/s
InnoDB 100W:379/s
[MySQL 配置文件] (缺省配置)
# MySQL Server Instance Configuration File
[client]
port=3306
default-character-set=gbk
[mysqld]
port=3306
basedir="C:/mysql50/"
datadir="C:/mysql50/Data/"
default-character-set=gbk
default-storage-engine=INNODB
sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections=100
query_cache_size=0
table_cache=256
tmp_table_size=50M
thread_cache_size=8
myisam_max_sort_file_size=100G
myisam_max_extra_sort_file_size=100G
myisam_sort_buffer_size=100M
key_buffer_size=82M
read_buffer_size=64K
read_rnd_buffer_size=256K
sort_buffer_size=256K
innodb_additional_mem_pool_size=4M
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=2M
innodb_buffer_pool_size=159M
innodb_log_file_size=80M
innodb_thread_concurrency=8
【总结】
可以看出 在MySQL 5.0里面,MyISAM和InnoDB存储引擎性能差别并不是很大,针对InnoDB来说,影响性能的主要是 innodb_flush_log_at_trx_commit 这个选项,如果设置为1的话,那么每次插入数据的时候都会自动提交,导致性能急剧下降,应该是跟刷新日志有关系,设置为0效率能够看到明显提升,当然,同样你可以SQL中提交“SET AUTOCOMMIT = 0”来设置达到好的性能。另外,还听说通过设置innodb_buffer_pool_size能够提升InnoDB的性能,但是我测试发现没有特别明显的提升。
基本上我们可以考虑使用InnoDB来替代我们的MyISAM引擎了,因为InnoDB自身很多良好的特点,比如事务支持、存储过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多,当然,相应的在my.cnf中的配置也是比较关键的,良好的配置,能够有效的加速你的应用。
如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。
MySQL replication 详细配置
1. 设置master(1) 修改配置文件
# vim /etc/my.cf
在[mysqld]部分添加
server-id=1
log-bin=mysql-bin
改完后重启mysqld服务
# service mysqld restart
(2) 设置mysql数据库的root访问密码
# mysqladmin -u root password '123'
# mysql -u root -p 输入密码‘123’登陆mysql
mysql> grant replication slave on *.* to 'test'@'10.0.2.61' identified by '123';
说明:这里的test是为slave端设置的访问master端mysql数据的用户,密码为123,这里的10.0.2.61为slave的ip。
mysql> flush tables with read lock; 锁定数据库,此时不允许更改任何数据
mysql> show master status; 查看状态,这些数据是要记录的,一会要在slave端用到
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000022 | 229 | | |
+------------------+----------+--------------+------------------+
2. 设置slave
# vim /etc/my.cnf 在[mysqld]部分加入
server-id=2 //设置数据库id,可以随便设置,但是不能和Master重复。
# scp -r 10.0.2.62:/var/lib/mysql/库名/* /var/lib/mysql/库名 这里的/var/lib/mysql 是数据库的datadir,不要搞混了。从master把所有数据库文件拷贝到slave,目的是数据的一致,mysql库就不用拷贝了,因为slave上也有一些配置保存在mysql库里。
# service mysqld restart
# mysql -u root -p
mysql> slave stop; 停止slave服务
mysql> change master to
->master_host=‘10.0.2.61’, //主服务器的IP地址
->master_user='test', //同步数据库的用户
->master_password='123', //同步数据库的密码
->master_log_file='mysql-bin.000022', //主服务器二进制日志的文件名(前面要求记住的参数)
-> master_log_pos=229; //日志文件的开始位置(前面要求记住的参数)
注:有时需要指定主mysql的端口号,参数为 master_port=3306
mysql> unlock tables; master上打开锁定的数据库
mysql> slave start; 启动同步数据库的线程
mysql> show slave status\G;查看状态
确认以下两项参数都为yes
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
减少MySQL的Sleep进程有效方法
经常遇到很多朋友问到,他的MySQL中有很多Sleep进程,严重占用MySQL的资源,现在分析一下出现这种现象的原因和解决办法:1,通常来说,MySQL出现大量Sleep进程是因为采用的PHP的MySQL长链接数据库方式,即使用了mysql_pconnect来打开链接数据库,解决办法就是使用“短”链接,即mysql_connect函数。
2,在使用mysql_connect短链接方式打开数据库,每个页面在打开数据库后,执行SQL完成,当页面脚本结束的时候,这个MySQL连接会自动关闭并且释放内存。但仍然出现大量Sleep进程,可以看看网站是否存在以下几个方面的问题。
A,硬盘上存在大量的静态文件,或者WEB服务器负荷太重,在处理HTTP请求响应变得太慢,这样也有可能导致出现大量Sleep进程,解决方法适当调整WEB服务参数和文件,一味的静态或者缓存化网页内容并不是灵丹妙药。
B,在网页脚本中,有些计算和应用可能非常耗时,比如在0秒的时候打开数据库执行完一段SQL代码后,网页脚本随即花了20秒钟进行一段复杂的运算,或者是require了一个庞大的PHP文件(比如含有几千个违规关键字的过滤函数),哪么这个时候在MySQL后台看到的进程中,这个20秒的过程MySQL并没有做任何事情了,一直处于Sleep状态,直到这个页面执行完毕或者达到wait_timeout值(被强行关闭),优化网页脚本,尽量让程序快速运行,或者在执行这段耗时的运行过程中,执行mysql_close把当前MySQL链接强行关闭。
C,在采集站中,MySQL中大量的Sleep进程这类现象尤其明显(比如很多网友问道DeDeCMS的MySQL中出现大量Sleep),因为大部的采集器页面在运行过程中,事先打开了一个MySQL链接(可能是为了验证用户权限等),然后开始使用file_get_contents之类的操作去获取一个远程的网页内容,如果这个远程的站点访问速度太慢,比如花了10秒时间才把网页取回,哪么当前采集脚本程序就一直阻塞在这里,并且MySQL啥事也没干,一直处于Sleep状态。解决方法同上,在发出file_get_contents采集远程网页的时候,使用mysql_close强行关闭MySQL的连接,等采集完成在适当需要的时候再重新mysql_connect即可。
总的说来,MySQL是一个非常高效快速的数据库,要让他发挥到最大的性能,同时也不要过量的去掘取他的优势所在,适当的分表(超过10G的表,在打开和关闭以前更新的时候效率明显下降很多),尽可能的优化SQL都可以做到事半功倍的。
mysql 忘记root密码怎么办
如果忘记root密码或其他用户密码,不要急,按下面操作即可。1. 编辑mysql主配置文件 my.cnf
vim /etc/my.cnf
在[mysqld]字段下添加参数 skip-grant
2. 重启数据库服务
service mysqld restart
3. 这样就可以进入数据库不用授权了
mysql -uroot
4. 修改相应用户密码
use mysql;
update user set password=password(your password) where user="root";
flush privileges;
关于mysql
本帖最后由 wangjian 于 2011-7-26 21:15 编辑有一个人给我发了么一个内容的东西,让我去mqsql机器上跑一下,怎么跑呀?一个名为txt的文件?
CREATE DATABASE `tuan` DEFAULT CHARACTER SET utf8;
USE `tuan`;
CREATE TABLE deal (
id INTEGER NOT NULL AUTO_INCREMENT,
city_id INTEGER,
city_name VARCHAR(255),
title VARCHAR(1024),
merchant_id INTEGER,
merchant_name VARCHAR(255),
gp_deal_id INTEGER,
deal_id INTEGER,
gp_sellcount INTEGER default 0,
sellcount INTEGER default 0,
start_time TIMESTAMP,
end_time TIMESTAMP,
PRIMARY KEY (id)
) AUTO_INCREMENT=1000000000 DEFAULT CHARSET=utf8;
ALTER TABLE deal ADD INDEX index_deal_gp (gp_deal_id);
ALTER TABLE deal ADD INDEX index_deal_time (deal_id, start_time, end_time);
CREATE TABLE deal_upload (
id INTEGER NOT NULL AUTO_INCREMENT,
gp_deal_id INTEGER,
deal_id INTEGER,
ret_desc VARCHAR(255),
ret_code SMALLINT,
create_time TIMESTAMP,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_upload ADD INDEX index_upload_gp (gp_deal_id);
create table deal_code_verify (
id INTEGER NOT NULL AUTO_INCREMENT,
gp_deal_id INTEGER,
verify_code VARCHAR(20),
sn VARCHAR(20),
ret_desc VARCHAR(255),
ret_code SMALLINT,
use_time TIMESTAMP,
create_time TIMESTAMP,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_code_verify ADD INDEX index_verify_gp (gp_deal_id);
create table deal_code_query (
id INTEGER NOT NULL AUTO_INCREMENT,
gp_deal_id INTEGER,
verify_code VARCHAR(20),
ret_desc VARCHAR(255),
ret_code SMALLINT,
create_time TIMESTAMP,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_code_query ADD INDEX index_query_gp (gp_deal_id);
create table deal_cancel (
id INTEGER NOT NULL AUTO_INCREMENT,
gp_deal_id INTEGER,
ret_desc VARCHAR(255),
ret_code SMALLINT,
create_time TIMESTAMP,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_cancel ADD INDEX index_cancel_gp (gp_deal_id);
create table deal_sellcount (
id INTEGER NOT NULL AUTO_INCREMENT,
ret_desc VARCHAR(255),
ret_code SMALLINT,
data VARCHAR(2048),
create_time TIMESTAMP,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
create table sold (
id integer auto_increment primary key,
deal_id integer,
cnt integer comment 'count sold in tuan',
total_price decimal(12,2) comment 'total price',
our_cnt integer comment 'count sold in our platform',
index sold_deal_id (deal_id)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
create table sold_detail (
id integer auto_increment primary key,
deal_id integer,
sn varchar(128) comment ' tuan serial no',
no varchar(32) comment 'user no',
phone_no varchar(20) comment 'user phone no',
created timestamp comment 'created time',
index sold_detail_deal_id (deal_id)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON tuan.* TO 'stardeals'@'%' IDENTIFIED BY '5742d34l5' WITH GRANT OPTION;
Tencent64:/data #
ignored in --skip-name-resolve mode
以前也看到过这个错误信息,不过今天想彻底的研究一下。其实也不算错误,顶多就算是警告。查看错误日日志时,有如下信息:
110908 10:21:56 [Warning] 'user' entry 'root@server1‘ ignored in --skip-name-resolve mode.
110908 10:21:56 [Warning] 'user' entry '@server1' ignored in --skip-name-resolve mode.
网上查了下资料,才明白是这么回事:
skip-name-resolve 参数的目的是不再把域名解析成IP,这样可以加快数据库的反应时间。然而我们使用这个参数后,原来数据库中已经存在的域名就不能再被解析了。不妨先看看mysql库中相关的数据:
mysql> select user,host from user;
+------+------------------+
| user | host |
+------+------------------+
| root | 127.0.0.1 |
| | server1 |
| root | server1|
| | localhost |
| root | localhost |
+------+------------------+
这里面的host列正好和错误日中中的那个warning相吻合。既然已经不能解析成IP了,也就是说里面的server1已经不再生效了。删除得了。
mysql> delete from user where host='server1';
Query OK, 2 rows affected (0.00 sec)
删除后,错误日志中则不再出现类似的警告信息。
MySQL的Query Cache工作原理分析
本帖最后由 lqph3387 于 2011-3-29 16:47 编辑其实MySQL(和PHP搭配之最佳组合)有着很强大的功能,只是默认没有启用,这篇文章将为大家介绍MySQL(和PHP搭配之最佳组合)查询调整缓冲设置(query_cache),可以让MySQL(和PHP搭配之最佳组合)的速度提高至少5倍。
查询缓存存储SELECT查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。
如果你有一个不经常改变的表并且服务器收到该表的大量相同查询,查询缓存在这样的应用环境中十分有用。对于许多Web服务器来说存在这种典型情况,它根据数据库内容生成大量的动态页面
QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用 QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字 符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。
不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理:
过滤所有注释
去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。
下 面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在 不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三条SQL 会被存储在三个不同的缓存里,虽然它们的结果都是一样的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';
目前只有select语句会被cache,其他类似show,use的语句则不会被cache。
因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。
也 就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数据库的负 担,而不是减轻负担。我一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样 可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。
那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句 ——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL 文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。
存储块
在本节里“存储块”和“block”是同一个意思
QC 缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新 的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为 4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之 下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。
除了查询结果需要存储块之 外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数 量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果 用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。
通过观察Qcache_queries_in_cache和 Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的比例如果接近1:2,则说明当前的 query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比 Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。
Qcache_queries_in_cache*query_cache_min_res_unit(sql 文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可 以尝试减小query_cache_min_res_unit的值。
调整大小
如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。
启动参数
show variables like 'query_cache%'可以看到这些信息。
query_cache_limit:如果单个查询结果大于这个值,则不Cache
query_cache_size: 分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于40KB,则相当于禁用QC。QC存储的 最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。
query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用 SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。
query_cache_min_res_unit:每次给QC结果分配内存的大小
状态
show status like 'Qcache%'可以看到这些信息。
Qcache_free_blocks: 当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。
Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size
Qcache_hits:自mysql进程启动起,cache的命中数量
Qcache_inserts:自mysql进程启动起,被增加进QC的数量
Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。
Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等)
Qcache_queries_in_cache:当前被cache的SQL数量
Qcache_total_blocks: 在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果 要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个blocks,第一个block用来存储sql语句 文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个block为2KB(先allocate4KB,然后释放 多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个block来存储表信息。也就是说,block会被用在三处地方: 表信息,SQL文本,查询结果
查阅不少文档后,总结如下:
查询缓存区适合select 操作较多,而insert update delete操作较少的情况,并且重复的SQL查询越多,效果越好
mysql 5.0 升级5.1
为了满足业务需求,实现数据表的分区功能,最近做了一次mysql版本升级。步骤很简单:
1. 解压5.1版本的二进制安装文件。
2. 修改mysql 链接文件指向mysql5.1目录
3. 修改5.0和5.1之间不兼容的cnf参数,如--log_slow_queries改为--slow_query_log
4. 拉起mysql
5. 运行mysql5.1的mysql_upgrade 创建mysql.plugin,以及修复部分权限表的结构
6. 执行mysql_upgrade 过程中的修复提示
REPAIR TABLE `help_category`;
REPAIR TABLE `help_keyword`;
REPAIR TABLE `help_topic`;
REPAIR TABLE `proc`;
REPAIR TABLE `time_zone_name`;
7. 检查表数据及功能。
附注:mysql 升级注意事项
检查所有的变化,尤其注意那些标志为 "不兼容的变化" 的部分。详情请看附录 "mysql_update MySQL升级时检查数据表"
可能某些发布版本会改变授权表的机制
查看所有重大的变化,详情请看MySQL手册的 "D.1.1.?Changes in release 5.1.10 (Not yet released)" 章节
以下是升级到MySQL 5.1之后会发生的一些变化:
服务器部分:
不兼容的变化:MySQL 5.1 实现了支持无需重启服务器就能在运行时加载或卸载API插件。这个特性需要用到mysql.plugin表,可以运行 "mysql_upgrade" 命令来创建该表
插件安装在系统变量 plugin_dir 所指的目录下。这个变量也控制着用户自定义函数(UDFs)所在目录,这相对以前的版本有所改变。在MySQL 5.1中,所有的UDFs库必须都安装到 plugin_dir 目录下,从旧版本升级的时候,必须把那些库文件都移动到这个目录下
不兼容的变化:系统变量 table_cache 改名为 table_open_cache
不兼容的变化:在MySQL 5.1.6 中 FULLTEXT 的索引结构发生变化了。当升级到 5.1.6 甚至更高之后,需要对每个包含 FULLTEXT 字段的数据表执行 "REPAIR TABLE" 语句
在 MySQL 5.1.6 以前,MySQL把普通的查询日志和慢查询都写到文件中。从5.1.6以后,这些日志可以灵活地选择是是写到日志文件中(跟以前一样)或者写到 mysql 数据库的 general_log 和 slow_log 表中。如果启用日志记录,这2种方式都可以使用。选项 --log-output 用来控制这2种日志的记录方式
从5.1.6开始,特殊字符集的数据库和表的标识符在创建相应目录和文件时都会用对应的字符集编码了
SQL分:



