嗯,基本上这些题都答得好 那就… 直接上题.
这是一篇译文,原文地址是: http://www.mysqlperformanceblog.com/2009/06/15/testing-fusionio-strict_sync-is-too-strict/
随着新的更新FusionIO驱动的更新,我能够在我的戴尔R900与Ubuntu 8.10上进行尝鲜,而不再需要痛苦地编译驱动或是降级kernel.现在我决定测试一下strict_sync模式。
据我所知FusionIO默认情况下,比如英特尔的SSD ,是对应用程序“撒谎”了,fsync()并不是真正的发生了,它仍然只是提交到了内存而不是最终的磁盘。FusionIO还有一个“ strict_sync ”模式,可以保证fsync函数可靠地操作。
好啊兄弟,让我们来压一下性能—通常我在100w数据(约9GB数据),O_DIRECT模式下开着3GB的buffer_pool来搞这个测试。 原始测试数量参见这里 结果用TPM (每分钟的事务数)表示 ,这样更清楚一些。图形显示,结果是是随着时间[X轴]不断变化 。 这个图形已经很明显,我都不需要再用文字来说明了。。。
但是我没有测试,在断电的情况下,在默认模式下处理、结束事务的情况。这个需要读者您检查一下。
原文地址:http://www.mysqlperformanceblog.com/2009/06/15/how-to-pretty-print-mycnf-with-a-one-liner/ 当我在一台服务器上转悠时,我会经常想看看/etc/my.cnf文件格式,当然是想看格化美观,没有注释的。这样的一行Perl就能将美化输出文件:
1.perl -ne ‘m/^([^#][^\s=]+)\s*(=.*|)/ && printf(”%-35s%s\n”, $1, $2)’ /etc/my.cnf 2.[client] 3.port = 3306 4.socket = /var/run/mysqld/mysqld.sock 5.[ mysqld_safe ] 6.socket = /var/run/mysqld/mysqld.sock 7.nice = 0 8.[ mysqld ] 9.user = mysql 10.pid-file = /var/run/mysqld/mysqld.pid 11.socket = /var/run/mysqld/mysqld.sock 12.port = 3306 13…..
原文地址:http://www.mysqlperformanceblog.com/2009/06/16/slow-drop-table/
大家都知道,Ext3并不是最有效的文件系统,例如,删除文件会非常缓慢(那真是一个痛苦的过程,不是吗老兄?),造成大量的随机I / O。然而事实上,有时候它比你想象的更能影响MySQL的性能。那么,什么时候会发生,又为什么会发生呢?
当您运行DROP TABLE时,会有好几件事情需要去做:对表进行write lock,这样它不会被其他线程使用;存储引擎删除数据文件;当然,最后MySQL会删除表定义文件(.frm文件)。这还不是所有的事,还有另外一件事需要去做:
DROP TABLE
这整段删除表操作的代码都被LOCK_open互斥信号量所包围。这个互斥信号量在MySQL中不少地方都用到过,但主要是表在开启或关闭的时候。这意味着,当LOCK_open锁定时,没有查询语句可以执行,因为他们阻止任何访问。
LOCK_open
这就解释了在ext3文件系统上删除10GB的文件何时成为了痛苦的等待的开始。删除10GB的文件将持续一段时间,如果这是一个MySQL表,这段时间mutex里将会一直存在,而这个互斥会拖延所有查询。
我尝试了一些替代的办法,让MySQL来在DROP TABLE时删除小文件,以尽量减少影响,如:
不幸的是,原来所有管理指令:ALTER TABLE <ALTER ALTER TABLE或OPTIMIZE TABLE实际都一样,或是在旧的表文件删除时使用了其他的LOCK_open互斥信号锁。
ALTER TABLE
OPTIMIZE TABLE
唯一的选择似乎就只能是改变文件系统了。例如,换成处理文件删除更有效的XFS文件系统。
EXT3
的xfs
一个MySQL的内部操作可能更好一点:可以通过先重命名对应的数据文件,再在没有互斥信号锁的情况下删除物理文件。但是事实上可能没有那么简单,因为实际的删除操作是由存储引擎来完成的,因此不是MySQL的代码能控制的。
这肯定不是一个共同的情况,但是有时候(虽然我们极其不愿)确实可能会让任何人头痛(例如,删除一个老的不再使用的表) 。
这里绍明同学说应该翻译成:这不是一个常见的情况,但是它可能会在最不期望出现的时候成为一个问题(例如 删除没有使用的旧表).
一个评论回复说:
从一个完全不同的领域的解决办法。 mythtv (电视记录系统)开发者们在ext3系统上删除大型文件时,通过“缓慢删除”功能取得更好的效果。一般来说,电视录音大概1 – 12GB每小时,所以一部电影可以20 + GB大小的文件。如果没有该功能,删除文件操作将锁定ext3整个系统约20-30秒。 “慢删除”只是在后台执行将文件中的块清空的操作。
从一个完全不同的领域的解决办法。
mythtv (电视记录系统)开发者们在ext3系统上删除大型文件时,通过“缓慢删除”功能取得更好的效果。一般来说,电视录音大概1 – 12GB每小时,所以一部电影可以20 + GB大小的文件。如果没有该功能,删除文件操作将锁定ext3整个系统约20-30秒。
“慢删除”只是在后台执行将文件中的块清空的操作。
另一个评论说:
我应该指出,这并不只适用于MyISAM表,对于InnoDB表,在innodb_file_per_table模式下也一样。 我最近刚跟客户做了个spoke,他们几乎无法删掉一个400G的表,因为这个操作阻塞了很长时间。。
更改字符集设置 原文设置:http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/
Web世界已经走向UTF8;Drizzle选中它作为默认的字符集。大多网站后端用utf-8来存储文本数据,另外那些用latin1字符集的网也开始将他们的数据库迁移到utf8;google一下”mysql convert charset to utf8″,可以找到大量的网站,每个途径都有些微的不同,又在某些方面都有些不对。我会总结一下这些方法,说明他们为什么不奏效,然后给出一段脚本,大致上可以用来转换一个数据库或是一系列表到目标字标集。
方法一: ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 拿这个数据表作例子,我们可以看到这种方法为啥子行不通呢。 SQL:
1. mysql> CREATE TABLE `t1` ( 2. -> `c1` text NOT NULL 3. -> ) ENGINE=MyISAM DEFAULT CHARSET=latin1; 4. Query OK, 0 rows affected (0.02 sec) 5.
6. mysql> ALTER TABLE `t1` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci; 7. Query OK, 0 rows affected (0.02 sec) 8. Records: 0 Duplicates: 0 Warnings: 0 9.
10. mysql> SHOW CREATE TABLE `t1`\G 11. *************************** 1. row *************************** 12. TABLE: t1 13. CREATE TABLE: CREATE TABLE `t1` ( 14. `c1` mediumtext NOT NULL 15. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 16. 1 row IN SET (0.01 sec)
注意这里的c1隐含的从text到mediumtext的转换。这种方法能引起改变的数据类型和没有提示的截断,这从我们的目的上说是不能接受的。
方法二[在这里记录着]:
这种方法在转换之前,把所有的数据都转成了他二进制相似的数据类类型,避免了隐含的类型转换。由于实现方式的限制,他把原来以二进制形式存储的数据列也转成了文本的近似列。另外,这种方式有可能因为二进制数据不能进行全文检索而失败。即使这些解决了,这个过程也因为它过多的在每个表上执行alter语句而不能用在大数据量的数据库上。这些语句包括: 1) Drop FULLTEXT indexes 2) Convert target columns to their binary counterparts 3) Convert the table to the target character set 4) Convert target columns to their original data types 5) Add FULLTEXT indexes back 由于这些语句有时执行一句我们都需要花上n个钟头(我们是不是该庆幸是用小时来计数而不是用天来计数?),这也是不可接受的。
方法三: 导出整个数据库,再导入进去。当然,导入导出时选用正确的server端和client端字符集。 这是一个有三个步骤的过程。我们先导出数据库结构,然后手工编辑把数据字符集修改正确,接出单独导出数据。接下来,创建数据表结构,导入数据。如果你在使用复制(replication),这通常不太可取,因为这样导致可笑的一大堆日志,并引起复制链上所有服务器重新载入数据。 除开方法一之外,这些方法都不必要地麻烦。针对方法一,考虑一下下面这个alter语句: 1. ALTER TABLE `t1` 2. DEFAULT CHARSET=utf8, 3. MODIFY COLUMN `c1` text CHARACTER SET utf8; 这个语句能转换整个表的默认字符集和目标数据表列的字符集,并且保持全文索引不变。对于一个指定的数据表,只需要一句sql语句。一个perl脚本已经写好了,它可以将这个alter table 的操作原子化,您可以从这里下载: $ wget http://www.pablowe.net/convert_charset 当这个脚本完成后,它会加到launchpad的Percona Tools 中去(也许是maatkit,如果证明是足够有用的话).它的一些不错的特性包括: 1.对字符型外键的恰当处理。(当下还没搞定,不过你可能最好不要使用字符型外键) 2.可以调节这个脚本创建的线程数目。(目前是每个表一个线程). 用法: Usage: convert_charset –database=database [options] Options: –askpass Prompt for a MySQL password –charset The target character set to convert to –collate The target collation to convert to –database|d The target database –help|? Display this help and exit –host|h The target host –ignore-columns Columns to ignore, useful if you want to keep the existing charset for a target column Comma-separated. NO SPACES. table.column –ignore-tables A comma-separated list of tables to ignore –password|p The MySQL password to use –port The target port –tables A comma-separated list of tables to convert. All non-named tables will be ignored –test Print the ALTER statements that would be executed without executing them. –user|u The MySQL user –version|V Display version information and exit defaults are: ATTRIBUTE VALUE ————————– —————— askpass FALSE charset utf8 collate No Default Value database No Default Value help FALSE host localhost ignore-columns No Default Value ignore-tables No Default Value password No Default Value port 3306 tables No Default Value test FALSE user Current User version FALSE