在Oracle这样的关系数据库中,游标是SQL的一个内存工作区,其作用就是用于临时存储从数据库中提取的结果数据块。Oracle的游标在PL/SQL编写存储过程时会经常用到,可以用于一些特殊的控制和曹走。而MongoDB也提供了游标这个定义—当然MongoDB的”存储过程”就是一段javascript的代码块。
Continue reading
Category Archives: Database
MongoDB Cursor
MongoDB的DML
MongoDB的DML同样包括插入(insert), 修改(update)和删除(remove)的功能,但MongoDB并不具备关系数据库中的事务性操作,这也导致了MongoDB在很多时候不能使用像关系数据库那样的事务场景。但MongoDB中的update,findAndModify等操作都是原子操作,一定程度上弥补了这方面的不足。 Continue reading
MongoDB的DDL
MongoDB是文档数据库,每一个记录是一个独立的文档(Document),而文档是由多个field-value pairs所组成,这决定了MongoDB的逻辑对象与关系数据库有很大的区别。官方文档中的SQL to MongoDB Mapping Chart 中有对逻辑对象的信息的描述:
RDBMS | MongoDB |
---|---|
database | database |
table | collection |
row | document or BSON document |
column | field |
index | index |
table joins | embedded documents and linking |
primary key(Specify any unique column or column combination as primary key. |
primary key In MongoDB, the primary key is automatically set to the _id field. |
aggregation (e.g. group by) | aggregation pipeline See the SQL to Aggregation Mapping Chart. |
【译】MySQL – The binary log
文档:http://dev.mysql.com/doc/refman/5.7/en/binary-log.html
二进制日志(binary log)描述了数据库的改变事件(event)(例如表的创建操作和表数据的变更),以及这些语句的执行时间。除非开启了行级日志功能,它同样包含了可能产生变更的语句的事件(例如,一个删除0行的DELETE语句)。总的来说相当于Oracle中的online redo log + archived redo log的功能。
二进制日志主要有两个目的:
用于复制(replication),master复制服务器上的二进制日志提供跪了数据改变的事件记录,然后将二进制日志中的这些记录发送给slave服务器,slave服务器再去应用这些记录。
包含数据恢复的操作需要使用二进制日志。在一个备份被恢复(restore)以后,二进制日志中的事件记录将会重新执行(recover),这样数据库就从备份的时刻恢复(recover)到最新的时刻。
“Point-in-Time (Incremental) Recovery Using the Binary Log”.http://dev.mysql.com/doc/refman/5.7/en/point-in-time-recovery.html
当使用不修改数据的SELECT或者SHOW时,二进制日志不会被用到。如果需要记录所有日志,而需要一般查询日志。
当服务器开启二进制日志时,性能会略微收到影响。然而,二进制日志可以带来建立复制、恢复等功能大大超过性能上的损失。二进制日志是 crash-safe的,只有完整的事件或者事务才会被记录或者重新执行。
相关选项
可以使用--log-bin[=base_name]
选项来开启日志,如果不给定base_name,默认的base_name名字是pid-file选项的值(默认是主机名加上-bin)。如果指定base-name而没指定路径时,则会使用数据的目录。建议指定base_name信息。如果你提供了日志信息的扩展名(例如 --log-bin=base_name.extension
),那么这个扩展名会被忽略。
mysqld会在二进制日志base_name的基础上添加一个数字扩展名,当新日志生成时该数字会+1,从而形成一个文件序列。服务器会在重启、冲刷(flush)日志时、改变现有日子大小(max_binlog_size)时创建一个新的文件。当使用长事务时,二进制日志可能会超过max_binlog_size
的大小限制,因为必须以一个完整的事务片形式写入一个文件,不能跨文件存储一个事务。
为了追踪哪些日志文件被使用,mysqld会创建一个二进制日志索引文件。该文件中包含了所有使用过的二进制日志文件名。默认情况下,索引文件有和二进制文件相同的basename加上扩展名.index。可以通过–log-bin-index[=file_name]修改,该选项不能在运行时修改,否则会让mysqld进程找不到该文件。
”二进制日志文件“这个术语一般指的是包含数据库事件记录的以数字结尾的日志文件,而”二进制日志“指的是这些日志文件加上日志索引文件的集合。
以SUPER权限登录的客户端可以使用SET sql_log_bin=0
来禁用二进制日志功能。
默认情况下,服务器通过记录事件(event)本身和事件信息的长度来保证他们会正确得被写入。你也可以通过设定binlog_checksum信息来让服务器写入校验信息。 当读取二进制日志信息时,master服务器默认使用长度来验证事件信息,可以通过设置 master_verify_checksum系统变量来使用校验和信息。slave服务器的I/O线程会验证从master服务器接收的事件信息,同理可以用slave_sql_verify_checksum来使用校验和验证。
二进制日志中记录的事件是根据MySQL版本、二进制日志格式不同而不同的。MySQL的二进制格式支持三种类型:基于行的日志、基于语句的日志和混合日志。
--binlog-do-db
和--binlog-ingore-db
选项同--replicate-ignore-db
和--replicate-do-db
选项的功能相同,用于筛选使用二进制日志、同步所用到的数据库。
一个slave服务器默认不将应用master所作出的数据改变写它自己的二进制文件中,如果需要记录这些改变,则需要以--log-slave-updates
变量的方式启动slave服务器,并开启 --log-bin
选项。你可以用 RESET MASTER或者PURGE BINARY LOGS语句来清理二进制日志。后者是前者的一个子集—RESET_MASTER(Deletes all binary logs listed in the index file, resets the binary log index file to be empty, and creates a new binary log file.),直接清理所有bin-log并清空索引文件(bin-log序号重新从1开始排),有可能导致复制的失败。PURGE BINARY LOGS不会清理当前bin-log。
当使用复制时,应该确保bin-log已经传到slave上再删除二进制文件。可以使用mysqladmin flush-logs
来清除几天前的bin-log,比PURGE BINARY LOGS
用起来更安全。
你可以通过mysqlbinlog
工具来显示二进制文件的内容,这个工具可以用来做恢复(recover)操作时重演二进制日志中的语句:
shell> mysqlbinlog log_file | mysql -h server_name
mysqlbinlog也可以用于显示复制slave relay 日志文件内容,因为这些文件和二进制日志的格式相同。
在一个语句或者事物执行完成时,二进制日志就会立即被写入。这保证了日志的写入是以提交顺序进行。
对非事务(nontransactional )表的更新将会在语句执行时立即写入二进制日志。
在一个未提交的事务之中,所有改变事务型表(例如InnoDB表)的更新(UPDATE, DELETE, 或INSERT)会被缓存,直到一个commit语句被执行。此时,mysqld会把全部的事务写到二进制日志中。
对于非事务表的修改不能被回滚。如果一个包含非事务表操作的事务被回滚,整个事务会被记录,并以一个ROLLBACK语句语句结束,从而保证对这些表的修改可以被复制。
当一个线程处理事务开始时,它分配binlog_cache_size
大小的缓冲区来缓冲语句信息。如果一个语句的长度超过这个限制,那么线程会打开一个临时文件来保存这个信息,并在使用完后删除它。Binlog_cache_use
状态变量(status variable)显示了使用这个缓冲区的事务数量(也可能使用一个临时文件),而Binlog_cache_disk_use
状态变量显示有多少事务在使用一个临时文件。这两个变量可以用作调整binlog_cache_size
大小的语句,从而避免使用临时文件。
max_binlog_cache_size
系统变量 (默认4GB, 也是最大值。最小值是4096B) 可以用来限制缓存多语句的事务的总大小。如果一个事务远大于这个值,它可能会执行失败并回滚。
如果你使用二进制日志和基于行的日志,在执行CREATE ... SELECT
或者 INSERT ... SELECT
语句时,并行插入会被转换成普通的插入。这样做的目的是为了保证你在执行恢复备份时可以重建为一个准确的表副本。如果你使用基于语句的日志时,原始的执行语句会被写入日志。
默认情况下,二进制日志不会每次同步地写入磁盘。所以如果操作系统或者主机崩溃时, 可能有二进制日志中最后一个语句丢失的情况。为了避免这种情况,你可以使用sync_binlog系统变量让二进制日志在每次写入时同步到磁盘。对于该选项,1是最安全的方式,但是性能最差。例如,当你使用InnoDB表,而MySQL服务器正在处理一个COMMIT语句时,它会先将整个事务写入二进制日志中然后再将提交操作交付给InnnoDB。如果服务器在两个操作之间崩溃,二进制中存在的该事务依然会在下启动时被InnoDB回滚。为了避免这种情况,可以设置 --innodb_support_xa
为1。虽然这个选项关联InnoDB XA 事务, 它也会保证二进制日志和InnoDB数据文件被同步。由于这个同步功能极大的提高了MySQL服务器的安全性,InnoDB默认启用了同步(sync_binlog=1
)。
下面的系统变量会话值将写入二进制日志并在slave服务器读二进制日志时被解析:
sql_mode (除了 NO_DIR_IN_CREATE
模式不会被复制)
foreign_key_checks
unique_checks
character_set_client
collation_connection
collation_database
collation_server
sql_auto_is_null
^^
【译】MySQL – The Error Log
文档地址:http://dev.mysql.com/doc/refman/5.7/en/error-log.html
错误日志(error log)包含mysqld启动和关闭过程信息,影响服务器运行的严重的错误也会记录在其中。如果mysqld通知一个表需要自动检查并修复时,它也会将信息写到error log中。
当设了 --syslog
选项, mysqld_safe arranges for the server’s stderr to be sent to the syslog facility, as described later.)
在Unix或者类Unix系统上, mysqld输出error log信息的规则如下:
不指定--log-error
, mysqld 会将错误信息输出console上。”console”即stderr,标准错误输出。
当指定--log-error[=file_name]
, mysqld会将错误信息写到一个日志文件里。如果没有指定路径信息,将日志文件写到数据的目录中。如果没有指定任何文件名,则默认使用数据的目录下的host_name.err。
当设置mysqld将错误日志写到文件,执行FLUSH_LOGS
或mysqladmin flush_logs
日志flush操作时,服务器会关闭并重新打开日志文件。所以如果需要保存日志,需要在flush日志前手动将错误日志文件改名,这样flush就会重新创建一个文件。例如, 可以使用下面命令保留旧日志。
1 2 3 |
shell> mv host_name.err host_name.err-old shell> mysqladmin flush-logs shell> mv host_name.err-old backup-directory |
如果使用mysqld_safe来启动mysqld时,mysqld_safe会将mysqld的错误信息写到错误文件或者syslog中。mysqld_safe有三个相关选项:
--syslog
使用syslog来记录日志。开启则写到–log-error中。
--skip-syslog
没有任何日志选项时的默认配置,将日志写入到错误日志中。
--log-error
将错误日志写到文件里(规则同上)。写到[mysqld], [server]和[mysqld_safe]组中的log-error选项,mysqld_safe都会使用。
Continue reading
【译】MySQL – The General Query Log
mysqld会将客户端连接和断开连接的信息,以及从客户收到的SQL语句写到一般查询日志中(记录从客户端收到的SQL语句,这个信息可能和具体执行的语句不同)。一般查询日志的顺序和二进制日志(binary log)中的顺序不同,因为一些语句需要等待锁资源释放才会被执行。另外,只查询数据的语句不会记录到二进制日志中。
当使用基于语句(statement-based)的日志功能时,所有的日志都会写入到查询日志中;而使用基于行(row-based)的日志功能时,即binlog_format=row
,updates会被记录为行的改变向量而非SQL语句,因而这些SQL语句不会记录到查询日志中。当binlog_format=MIXED
时,update语句也不会写到查询日志中。
在默认情况下,一般查询日志没有启用。需要使用 --general_log[={0|1}]
来启用,--general_log
即设置为1。指定一般查询日志文件名: --general_log_file=file_name
。使用--log-output
来指定日志的目标。(见上一节http://debugo.com/mysql-flush-log-output/ )。如果没有指定日志文件名,默认的文件名host_name.log。如果没有指定路径名,则默认使用数据文件目录。--general_log
和--general_log_file
可以在运行时修改。
当服务器启动时,启动信息会记录在一般查询日志文件中(无论log-output是否为FILE)。后续的日志需要在log-output=FILE
时才会写入日志文件中;如果log-output=NONE
,而查询的信息不会被记录。
重启服务器后者执行日志冲刷(flush)操作不会导致新的日志文件的生成(仅仅是关闭并重新打开)。可以使用下面的方法实现日志轮滚的功能:
1 2 3 |
shell> mv host_name.log host_name-old.log shell> mysqladmin flush-logs shell> mv host_name-old.log backup-directory |
或者在运行时关闭一般查询日志的功能:SET GLOBAL general_log = 'OFF';
关闭日志后,再通过操作系统命令重命名文件。然后开启日志:SET GLOBAL general_log = 'ON';
会话级变量sql_log_off可以设置为ON或者OFF用于为当前会话打开/关闭一般查询日志的功能。
语句中的密码在写入一般查询日志时会被服务器重写,不会以明文方式记录。这个功能可以使用--log-raw
选项禁用,常用于调试目录。隐式的密码重写语句不会被解析,所以不会记录到一般查询日志中。
对于MySQL 5.7.2版本,log_timestamps系统变量控制写入一般查询日志(慢查询日志和错误日志)的时间戳时区信息,当写入日志表时的时区信息根据time_zone系统变量来设定。
使用Scala Casbah连接MongoDB
Casbah是Scala的MongoDB toolkit,它对java Driver进行了封装并提供了scala风格的接口。Casbah使用了隐式的“PIMP My Library”代码来增强Java代码的功能。PIMP My Library模式是使用额外的方法和属性来装饰类的一种方法,一般使用隐式函数定义的方式来让Scala转换一个对象为一个新的对象,参考PIMP My Library,下面是一个简单的PIMP My Library用例:
1 2 3 4 5 6 7 8 9 |
scala> class QuotaString(str:String) { | def quota= "\"" + str + "\"" | } defined class quotaString scala> implicit def strWithQuota(str:String) = new QuotaString(str) scala> "hello, scala".quota res0: String = "hello, scala" |
MongoDB Casbah运算符
Casbah通过运算符提供了非常灵活的语法,用于构建DBObject文档对象。
Continue reading
Mongo – Class One
1. Concept
MongoDB的文档数据库特性表示对非结构化存储的支持非常好,即不能确定表的列结构的数据。这类数据无法固定模式/模型,数据结构持续变化中,数据库管理员和开发人员的压力被扩大。但多媒体这类二进制数据为”非结构化“数据并不准备。例如:调查表。每个被调查公司的调查项都不一样
MongoDB具有一些特点
· 面向文档的存储引擎,可以方便支持非结构化数据
· 全面的索引支持,可以在任意属性上建立索引
· 数据库本身内置的复制和高可用
· 数据库本身支持的自动分片集群
· 丰富的基于文档的查询功能
· 原子化的数据操作
· 支持Map/Reduce
· GridFS
MongoDB有下面三种逻辑对象
文档:mongoDB的“行”以json的形式表示(key-value的集合),称为一个document(文档),例如{“foo”:3, “greeting”:”hello world”}。注意一个文档中的key不能重复。文档中可以嵌入文档。
集合:一组文档的集合,文档类似于关系数据库中的行而集合类似于关系数据库里的表。集合是无模式的,即集合中的文档可以五花八门,没有固定格式。
数据库:由多个集合组成
Continue reading
MySQL Reading Note – Log Flushing & Output
MySQL服务器有很多日志,可以帮助你找到当前正在运行的活动。
Log Type | Information Written to Log |
---|---|
Error log | Problems encountered starting, running, or stopping mysqld |
General query log | Established client connections and statements received from clients |
Binary log | Statements that change data (also used for replication) |
Relay log | Data changes received from a replication master server |
Slow query log | Queries that took more than long_query_time seconds to execute |