0%

MySQL日志

MySQL中有六种日志文件,分别是事务日志(分为重做日志(redo log)和回滚日志(undo log))、二进制日志(bin log)、错误日志(error log)、慢查询日志(slow query log)、一般查询日志(general log)、中继日志(relay log)。

事务日志

事务的隔离性是由锁来实现的,原子性、一致性、持久性是通过undo log和redo log来实现的

重做日志 redo log(Innodb特有的)

用于保证事务的原子性和持久性,有两部分组成,一是内存中的重做日志缓冲(redo log buffer),二是重做日志文件(redo log file)

InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)

Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。

于是,redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到磁盘,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求

事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中,当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖),在redo log中记录的是物理数据页面的修改信息

redolog 是物理日志,记录的就是数据页变更

阅读全文 »

scala集合

scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问,包含有三大类,Seq序列、Set集合、Map映射
不可变集合:scala.collection.immutable

集合本身不能动态变化

不可变集合

可变集合:scala.collection.mutable

集合本身是可以动态变化的

可变集合层级关系

阅读全文 »

scala隐式函数

在低精度数值向高精度数值转换时是自动进行转换的,而高精度数值向低精度数值转换时就需要手动的进行强制类型转换,可以使用隐式函数来优雅的解决这种问题

隐式函数implicit

隐式函数是以implicit关键字声明的单个参数的函数,这种函数将会自动应用,将值从一种类型转为另一种类型

1
2
3
4
5
6
7
8
// 隐式函数  将Double自动转化为Int
implicit def f1(d:Double): Int ={
d.toInt
}

// 引入隐式函数
import com.zhanghe.study.study_scala.oop.TestImplicit.f1
var i:Int = 2.0
阅读全文 »

scala抽象类

java中有抽象类概念,scala中同样也有,且同样是abstract关键字

在scala中抽象方法不需要使用abstract修饰,只是不写方法体而已,抽象字段是指没有初始化的字段

1
2
3
4
5
6
7
8
9
abstract class Parent{
// 抽象字段,抽象字段是一个没有初始值的字段
var age:Int

var name:String = _

// 抽象方法
def breath()
}
阅读全文 »

scala类型检查

要测试某个对象是否属于某个给定的类,可以用 isInstanceOf方法。用asInstanceOf方法将引用转 换为子类的引用。classOf获取对象的类名。

  • classOf[String]就如同Java的 String.class

    1
    2
    3
    4
    // classOf获取类
    val clazz:Class[Tiger] = classOf[Tiger]
    // class com.zhanghe.study.study_scala.oop.Tiger
    println(clazz)
  • 也可以使用反射来获取类

    1
    2
    3
    val tiger:Animal = new Tiger
    // class com.zhanghe.study.study_scala.oop.Tiger
    println(tiger.getClass)
  • obj.isInstanceOf[T]就如同Java的obj instanceof T 判断obj是不是T类型

    1
    2
    3
    4
    5
    val tiger:Animal = new Tiger
    // true
    println(tiger.isInstanceOf[Animal])
    // true
    println(tiger.isInstanceOf[Tiger])
  • obj.asInstanceOf[T]就如同Java的(T)obj 将obj强 转成T类型

    1
    2
    3
    4
    5
    val tiger:Animal = new Tiger
    // 判断类型是否为Tiger,如果是的话进行强转
    if(tiger.isInstanceOf[Tiger]){
    tiger.asInstanceOf[Tiger].run
    }