Mysql innodb 文件

Innodb数据存储

Innodb存储引擎将存储的数据按表空间进行存放,默认会一个10MB, 名字为ibdata1的文件

innodb_data_file_path = ibdata1:2000MB; ibdata2:2000MB:autoextend;

设置了innodb_data_file_path 参数以后所有innodb引擎的数据都会保存在设置的文件里面
当参数innodb_file_per_table设置了以后, 每个innodb表的将生成一个单独.idb的文件来存储数据, 这个单独的.idb表空间文件只存储该表的数据,索引和插入缓冲等信息. 其它的信息还是放在默认的表空间里面, 表空间又由段(segment),区(extent),页(page)组成.

Innodb 日志文件

在mysql文件下面有两个文件ib_logfile0和ib_logfile1, 这两个是innodb的日志文件,记录了innodb引擎的事务日志,也叫做innodb重做日志
重做日志文件的主要目的是,万一事务失败或者事务执行时断电,这时可以通过重做日志文件来恢复
设置参数:

  • innodb_log_file_size
  • innodb_log_file_in_group
  • innodb_mirrored_log_groups
  • Mysql 二进制文件

    二进制文件记录了对数据库执行的所有操作,不包括select和show. 开启二进制文件会使mysql性能下降百分之1
    作用:
    1. 恢复(recovery): 用户恢复数据
    2. 复制(replication): 可以使备用mysql服务器(slave)进行实时同步

    我的 datadir是/usr/local/var/mysql/.
    先确定log-bin是否则开启了

    mysql> show variables LIKE "log_bin"
    

    如果没有开启, 修改my.cnf

    log_bin=bin-log  #bin-log是名字
    

    此时再显示datadir目录会看到两个文件

    -rw-rw----     1 _mysql  _mysql   326B  6 14 17:52 bin-log.000001
    -rw-rw----     1 _mysql  _mysql    17B  6 14 17:52 bin-log.index
    

    bin-log.000001 二进制日志文件
    bin-log.index 二进制日志索引文件

    配置

    max_binlog_size=1024M
    

    查看日志, mysql自带了一个mysqlbinlog的工具

    sudo mysqlbinlog --start-position=1 bin-log.000001 | more
    

    Drupal 修改Node显示模式

    经常可能有这么一种需求,当判断node一个文件字段,传的是图片的时候用default显示,如果是传了视频那换种显示方式比如用摘要的显示模式去显示

    /**
     * Implements hook_entity_view_mode_alter().
     *
     * @param $view_mode
     * @param $context
     */
    function mymodule_entity_view_mode_alter(&$view_mode, $context) {
      if (!empty($context['entity']->type) && $context['entity']->type == 'material_other' && !empty($context['entity']->sco_manifest)) {
        $view_mode = 'teaser';
      }
    }
    

    Mysql 配置篇

    所有配置都可以通过show variables获取, 所有的配置和默认的一些设置都可以称为Mysql变量. 只是作用域的范围不一样而已, 配置分为动态和静态两种,动态意味着你可以在Mysql运行中修改,静态表示在Mysql整个生命周期都是内都是不能修改的. 可以使用set对动态参数进行设置.

    动态参数
    @@session 表示当前回话
    @@global 表示全局的

    设置用户变量

    set @test=1,@test2=2;
    

    设置系统变量, 当针对当前mysql的生命周期生效

    set @@session.read_buffer_size=51288;
    set @@global.read_buffer_size=51288;
    

    global 的修改会对全局生命,但不会覆盖mysql的配置文件,如果配置文件中有该配置那么该配置的优先级在一起global的设置,每个生命周期都是以配置中为的优先级最大.

    静态参数
    比如datadir这个参数就是只读的.

    查询

    select @@session.read_buffer_size  #当前生命周期的read_buffer_size
    select @@global.read_buffer_size   #全局的read_buffer_size
    

    内存配置
    InnoDB存储引擎内存由有几个组成部分:

    缓冲池 buffer pool(innodb_buffer_pool_size)

    缓冲池是占最大块内存的部分,用来存放各种数据的缓存。因为InnoDB的存储引擎的工作方式总是将数据库文件按页(每页16K)读取到缓冲池,然后按最近最少使用(LRU)的算法来保留在缓冲池中的缓存数据。如果数据库文件需要修改,总是首先修改在缓存池中的页(发生修改后,该页即为脏页),然后再按照一定的频率将缓冲池的脏页刷新(flush)到文件。可以通过命令SHOW ENGINE INNODB STATUS来查看innodb_buffer_ pool的具体使用情况

    innodb_buffer_pool_size 一般设置多大?
    查看innodb过去时间范围内的的状态,查看Buffer pool size大小, Buffer pool size * 16 / 1024 = 要设置的大小

    mysql > show engine innodb status\G; 
    

    查看配置大小

    show variables like 'innodb_buffer_pool_size';
    

    重做日志缓冲池 redo log buffer(innodb_log_pool_size)

    日志缓冲将重做日志信息先放入这个缓冲区,然后按一定频率将其刷新到重做日志文件。该值一般不需要设置为很大,因为一般情况下每一秒钟就会将重做日志缓冲刷新到日志文件,因此我们只需要保证每秒产生的事务量在这个缓冲大小之内即可。

    额外的内存池 additional memory pool (innodb_additional_mem_pool_size)

    额外的内存池通常被DBA忽略,认为该值并不是十分重要,但恰恰相反的是,该值其实同样十分重要。在InnoDB存储引擎中,对内存的管理是通过一种称为内存堆(heap)的方式进行的。在对一些数据结构本身分配内存时,需要从额外的内存池中申请,当该区域的内存不够时,会从缓冲池中申请。InnoDB实例会申请缓冲池(innodb_buffer_pool)的空间,但是每个缓冲池中的帧缓冲(frame buffer)还有对应的缓冲控制对象(buffer control block),而且这些对象记录了诸如LRU、锁、等待等方面的信息,而这个对象的内存需要从额外内存池中申请。因此,当你申请了很大的InnoDB缓冲池时,这个值也应该相应增加。

    自动哈希索引

    Innodb_adaptive_hash_index 用于启用或者禁用自适应hash索引

    innodb_fast_shutdown

    Innodb_fast_shutdown 参数告诉innodb在它关闭的时候该做什么工作,innodb_fast_shutdown影响着innodb表的行为,该参数有0,1,2三个值可以选择:
    0表示在innodb关闭的时候,需要purge all, merge insert buffer,flush dirty pages。这是最慢的一种关闭方式,但是restart的时候也是最快的。
    1表示在innodb关闭的时候,它不需要purge all,merge insert buffer,只需要flush dirty page,在缓冲池中的一些数据脏页会刷新到磁盘。(默认参数)
    2表示在innodb关闭的时候,它不需要purge all,merge insert buffer,也不进行flush dirty page,只将log buffer里面的日志刷新到日志文件log files,MySQL下次启动时,会执行恢复操作。

    innodb_force_recovery

    innodb_force_recovery影响整个InnoDB存储引擎的恢复状况。默认为0(设置范围1-6),表示当需要恢复时执行所有的
    恢复操作。当不能进行有效的恢复操作时,mysql有可能无法启动,并记录下错误日志。
    1. 1(SRV_FORCE_IGNORE_CORRUPT):忽略检查到的corrupt页。
    2. 2(SRV_FORCE_NO_BACKGROUND):阻止主线程的运行,如主线程需要执行full purge操作,会导致crash。
    3. 3(SRV_FORCE_NO_TRX_UNDO):不执行事务回滚操作。
    4. 4(SRV_FORCE_NO_IBUF_MERGE):不执行插入缓冲的合并操作。
    5. 5(SRV_FORCE_NO_UNDO_LOG_SCAN):不查看重做日志,InnoDB存储引擎会将未提交的事务视为已提交。
    6. 6(SRV_FORCE_NO_LOG_REDO):不执行前滚的操作。

    mysql 位置

    查看my.cnf位置

    $ mysql --help | grep my.cnf
    

    查看mysql data_dir位置

    $ ps -ef | grep mysqld
    

    或者

    $ show variables like 'datadir';
    

    用PHP实现一个简单的环形队列

    缺少一个好的计时器. 但是功能能正常运行. 替换成一个好的计时器。状态可以保存在DB中.

    /**
     * 环型队列.
     * 创建一个环形为3000个元素.
     * 作cron,其中每秒走一个位置.
     */
    
    /**
     * Class Task
     */
    class Task
    {
    
        private $TaskId;
        private $Time;
        private $CallBack;
        private $Run;
    
        public function __construct($TaskId = null, $Time = null, $CallBack = null)
        {
            $this->Run = FALSE;
            $this->SetId($TaskId);
            $this->SetTime($Time);
            $this->SetCallback($CallBack);
        }
    
        public function SetId($TaskId)
        {
            $this->TaskId = $TaskId;
        }
    
        public function GetId()
        {
            return $this->TaskId;
        }
    
        public function SetTime($Time)
        {
            $this->Time = $Time;
        }
    
        public function GetTime()
        {
            return $this->Time;
        }
    
        public function SetCallBack($CallBack)
        {
            $this->CallBack = $CallBack;
        }
    
        public function GetCallBack()
        {
            return $this->CallBack;
        }
    
        public function Run()
        {
            if (!$this->Run && is_callable($this->GetCallBack())) {
                $this->Run = TRUE;
                $this->GetCallBack();
            }
        }
    }
    
    /**
     * Class Mqueue
     *
     * 3000的环形队列.
     *
     */
    class Mqueue
    {
        private $Queue;
        private $Tasks;
        private $CurrentTask;
        private $QueueLenth = 3000;
        private $CurrentIndex; // 当前为在哪个格子里面.
        private $CurrentNum;  // 当前在第几圈.
    
        /**
         * Add task.
         *
         */
        public function AddTask(Task $task)
        {
            $this->Tasks[$task->GetId()] = $task;
            $this->CurrentTask = $task->GetId();
            $this->SetQueue($task);
        }
    
        /**
         * 将任务添加到环中.
         *
         * @param $task
         */
        private function SetQueue($task)
        {
            $postion = $this->GetPosition($task);
            $this->Queue[$postion[1]][$postion[0]][$task->GetId()] = $task;
        }
    
        /**
         * 计算任务在当前哪个环中.
         *
         * @param $task
         *
         * @return array
         */
        private function GetPosition($task)
        {
            $time = strtotime($task->GetTime()) - time();
    
            return [
              $time % $this->QueueLenth,
              $this->CurrentNum + floor($time / $this->QueueLenth),
            ];
        }
    
        private function Timer()
        {
            $this->CurrentIndex = 0;
            $this->CurrentNum = 0;
            $this->Ring();
        }
    
        public function GetQueue() {
            return $this->Queue;
        }
    
        /**
         * @TODO Good timer.
         */
        private function Ring() {
            // 每秒跑一格.
            // 到尾了跑第二环.
            for($i = 0; $i <= $this->QueueLenth; $i++) {
                $this->CurrentIndex++;
                if(isset($this->Queue[$this->CurrentNum][$this->CurrentIndex])) {
                    $this->Queue[$this->CurrentNum][$this->CurrentIndex]->Run();
                }
                sleep(1000);
    
                if($this->CurrentIndex <= $this->QueueLenth) {
                    $this->CurrentNum++;
                    $this->Ring();
                }
    
            }
        }
    }
    
    $task = new Task('thisismyfirsttask', '2017-3-21', function () {
            echo 'hello world';
        }
    );
    
    $mq = New Mqueue();
    $mq->AddTask($task);
    print_r($mq->GetQueue());