文章归档

从Oracle迁移到Mysql之前必须知道的50件事

本文翻译自Baron Schwartz(High Performance MySQL一书的主要作者)的blog, 原文链接: 50 things to know before migrating Oracle to MySQL

我本人比较关心的几点:

1. 对子查询的优化表现不佳.
2. 对复杂查询的处理较弱
4. 性能优化工具与度量信息不足
12. 支持SMP(对称多处理器),但是如果每个处理器超过4或8个核(core)时,Mysql的扩展性表现较差.
15. 没有基于回滚(roll-back)的恢复功能,只有前滚(roll-forward)的恢复功能.
18. 数据完整性检查非常薄弱,即使是基本的完整性约束,也往往不能执行。
20. 只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join).
21. 大部分查询只能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,但是查询优化器通常会低估其成本,它们常常比表扫描还要慢.
26. 每个存储引擎在行为表现、特性以及功能上都可能有很大差异.
28. 默认的存储引擎(MyISAM)不支持事务,并且很容易损坏.
30. 有些执行计划只支持特定的存储引擎.特定类型的Count查询,在这种存储引擎中执行很快,在另外一种存储引擎中可能会很慢.
31. 执行计划并不是全局共享的,,仅仅在连接内部是共享的.
33. 没有资源控制.一个完全未经授权的用户可以毫不费力地耗尽服务器的所有内存并使其崩溃,或者可以耗尽所有CPU资源.
45. 复制(Replication)功能是异步的,并且有很大的局限性.例如,它是单线程的(single-threaded),因此一个处理能力更强的Slave的恢复速度也很难跟上处理能力相对较慢的Master.
46. Cluster并不如想象的那么完美.或许我已经提过这一点,但是这一点值得再说一遍.
47. 数据字典(INFORMATION_SCHEMA)功能很有限,并且访问速度很慢(在繁忙的系统上还很容易发生崩溃).
48. 不支持在线的Alter Table操作.
50. 类似于ALTER TABLE或CREATE TABLE一类的操作都是非事务性的.它们会提交未提交的事务,并且不能回滚也不能做灾难恢复.Schame被保存在文件系统上,这一点与它使用的存储引擎无关.

50 things to know before migrating Oracle to MySQL
by Baron Schwartz,Translated by Jametong
1. 对子查询的优化表现不佳.
2. 对复杂查询的处理较弱
3. 查询优化器不够成熟
4. 性能优化工具与度量信息不足
5. 审计功能相对较弱
6. 安全功能不成熟,甚至可以说很粗糙.没有用户组与角色的概念,没有回收权限的功能(仅仅可以授予权限).当一个用户从不同的主机/网络以同样地用户名/密码登录之后,可能被当作完全不同的用户来处理.没有类似于Oracle的内置的加密功能.
7. 身份验证功能是完全内置的.不支持LDAP,Active Directory以及其它类似的外部身份验证功能.
8. Mysql Cluster可能与你的想象有较大差异.
9. 存储过程与触发器的功能有限.
10. 垂直扩展性较弱.
11. 不支持MPP(大规模并行处理).
12. 支持SMP(对称多处理器),但是如果每个处理器超过4或8个核(core)时,Mysql的扩展性表现较差.
13. 对于时间、日期、间隔等时间类型没有秒以下级别的存储类型.
14. 可用来编写存储过程、触发器、计划事件以及存储函数的语言功能较弱.
15. 没有基于回滚(roll-back)的恢复功能,只有前滚(roll-forward)的恢复功能.
16. 不支持快照功能.
17. 不支持数据库链(database link).有一种叫做Federated的存储引擎可以作为一个中转将查询语句传递到远程服务器的一个表上,不过,它功能很粗糙并且漏洞很多.
18. 数据完整性检查非常薄弱,即使是基本的完整性约束,也往往不能执行。
19. 优化查询语句执行计划的优化器提示非常少.
20. 只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort-merge join)与散列连接(hash join).
21. 大部分查询只能使用表上的单一索引;在某些情况下,会存在使用多个索引的查询,但是查询优化器通常会低估其成本,它们常常比表扫描还要慢.
22. 不支持位图索引(bitmap index).每种存储引擎都支持不同类型的索引.大部分存储引擎都支持B-Tree索引.
23. 管理工具较少,功能也不够成熟.
24. 没有成熟能够令人满意的IDE工具与调试程序.可能不得不在文本编辑器中编写存储过程,并且通过往表(调试日志表)中插入记录的方式来做调试.
25. 每个表都可以使用一种不同的存储引擎.
26. 每个存储引擎在行为表现、特性以及功能上都可能有很大差异.
27. 大部分存储引擎都不支持外键.
28. 默认的存储引擎(MyISAM)不支持事务,并且很容易损坏.
29. 最先进最流行的存储引擎InnoDB由Oracle拥有.
30. 有些执行计划只支持特定的存储引擎.特定类型的Count查询,在这种存储引擎中执行很快,在另外一种存储引擎中可能会很慢.
31. 执行计划并不是全局共享的,,仅仅在连接内部是共享的.
32. 全文搜索功能有限, [...]

从Oracle迁移到Mysql之前必须知道的50件事(转载).

本文转载Baron Schwartz(High Performance MySQL一书的主要作者)的blog, 原文链接: 50 things to know before migrating Oracle to MySQL

A while back I was at a seminar on migrating database applications to MySQL. A lot of the attendees were Oracle users. Based on their questions, comments and conversations during lunch, I made the following list of things Oracle users need to [...]

14 rules to improve web sites latency

Steve Souders’s 14 rules from his book High Performance Web Sites:

1. Make fewer HTTP requests
2. Use a CDN
3. Add an Expires header
4. Gzip components
5. Put stylesheets at the top
6. Put scripts at the bottom
7. Avoid CSS expressions
8. Make JS and CSS external
9. Reduce DNS lookups
10. Minify [...]

简述undo,redo与Recovery概念

本文翻译自Jonathan Lewis的Blog 文章Nutshell – 1, 简要描述undo,redo以及Recovery之间的相互关系.

简述undo,redo与Recovery概念
By Jonathan Lewis, Translated By Jametong

简述回滚(undo),重做(redo)与恢复(Recovery)概念.(标题中的”1”可能只是个乐观的说法,我不保证还有后续的简述.)

当你修改一个数据块时(修改表中的一条记录,或者标记一个索引条目为deleted状态),Oracle会做如下的事情:

• 生成一些redo(称为改变向量,change vector)来描述对应表数据块的变更

• 生成一些undo来描述数据修改前的版本

   o 这实际上还意味着生成一些redo(另外一个改变向量)来描述如何生成undo

• 将上述改变信息写入redo log buffer

   o 上述的改变向量对一起(回滚块的改变向量靠前)组成一个重做记录(redo record)

• 修改回滚数据块(undo block)

• 修改表数据块

在将表数据块与回滚数据块写到磁盘之前,必须确保重做日志已经写到磁盘.尽管如此,回滚数据块与修改后的表数据块最终还是会写到磁盘上,即使这次改变并没有被提交也是如此.

一个常见问题: 如果在事务提交之前,数据库就crash了,如果新的未提交的数据已经覆盖了磁盘上的旧有版本,Oracle将如何恢复数据.

答案: 当数据库crash后,恢复进程知道每个文件的最后的检查点时间,并应用重做日志恢复每个文件到最新状态.这个机制也会将回滚表空间恢复到最新状态,如同处理其它持久的表空间一样.

一旦数据库被恢复到最新状态,恢复进程就可以看到表数据块与回滚数据块的最新版本.由于回滚表空间(包含回滚段头(undo segment header)块,进而事务表(transaction table))是最新的,恢复进程可以发现这个事务没有提交,因此它可以做一次回滚操作以从回滚数据块上恢复表原来的数据.

脚注:

上面对数据改变的描述是最普遍的例子,还有一些显著提高这个机制的复杂性的特殊情况.特别是,如果你的变化是发生在事务开始的时候,还需要一些特殊的处理,在Oracle 10g的单实例数据库中,可以利用”私有重做线程(private redo thread)”与”基于内存的回滚(in-memory undo)”,对一个事务的最初几个变更做特别的优化.

请参考”Oracle词汇表”中”回滚段头(undo segment header)”与”事务表(transaction table)”的相关说明.

简述”parse calls”

本文翻译自Jonathan Lewis的Blog Entry Nutshell – 2

简述”parse calls”
By Jonathan Lewis, Translated By Jametong
关于统计信息”parse calls”的涵义,市面上流传着大量的含糊的说法.记住下面这一点很重要,这个统计项仅仅统计OCI库一种特定类型的调用(Call),一次parse call需要的工作量随着情境的不同可能会产生相差很大,有时它所做的工作量非常小,从而可以不用担心.

一次”parse calls”可能:

a) 不得不优化这条SQL语句,因为它无法在库缓存(Library Cache)中找到匹配项.

b) 在库缓存中找到了对应的语句,但是仍然由于各种原因需要对其进行优化,例如:之前的执行计划已经被刷出内存,或者由于不同的用户在调用,同样的SQL文本应用到了不同的对象.

(a),(b)是我们一般意义上理解的hasd parse

c) 在库缓存中找到了对应的SQL语句,并且不需要对其进行优化,因为它的执行计划仍然存在,并且用户也有相应的权限.

这一条是我们一般意义上理解的soft parse

d) 当通过session cursor cache或pl/sql cursor cache操作时,可以直接找到语句在库缓存中的位置,从而完全不需要搜索库缓存.

这一条是我们一般理解的soft soft parse (最初应该来自于Asktom的叙述)

当Oracle增加”parse calls”的计数器时,你仍然需要搞清楚这次调用到底对应于(a),(b),(c),(d)中的哪一类调用.
或许只是为了混淆问题,Oracle也可能仅仅记录一次”parse count(hard)”而不记录”parse call”.