binlog.index文件内容

记录了binlog文件的具体路径,在MySQL启动时,会找到binlog.index文件,然后读取它里面的条目,从而读取binlog文件。

cat /mysql/3306/data/master.index

/mysql/3306/data/master.000001
/mysql/3306/data/master.000002
/mysql/3306/data/master.000003
./master.000004
./master.000005
  1. binlog文件的路径可以是相对路径,也可以是绝对路径
  2. 如果是绝对路径,当文件被移动到其它地方时,只能手动修改对应的路径,否则MySQL在启动时,会报找不到文件路径的错误

设置binlog文件路径

可以在 my.cnf中设置binlog的文件路径

[mysqld]
log-bin=master

或设置为绝对路径

[mysqld]
log-bin=/mysql/3306/data/master

参数 log-bin身兼多职

设置后生效多个参数

  1. 表示启用 binlog功能
  2. 同时设置 binlog.index的文件名
  3. 同时设置binlog的文件名
show variables like '%log_bin%';
+---------------------------------+----------------------------------------------+
| Variable_name                   | Value                                        |
+---------------------------------+----------------------------------------------+
| log_bin                         | ON                                           |
| log_bin_basename                | /mysql/3306/data/master       |
| log_bin_index                   | /mysql/3306/data/master.index |
| log_bin_trust_function_creators | OFF                                          |
| log_bin_use_v1_row_events       | OFF                                          |
| sql_log_bin                     | ON                                           |
+---------------------------------+----------------------------------------------+

binlog文件的读取

MySQL在启动时会读取data目录下的所有以.index后缀的文件(默认值),然后在读取每个index文件中的条目

官方文档

The default location for binary log files and the binary log index file is the data directory. You can use the --log-bin option to specify an alternative location, by adding a leading absolute path name to the base name to specify a different directory. When the server reads an entry from the binary log index file, which tracks the binary log files that have been used, it checks whether the entry contains a relative path. If it does, the relative part of the path is replaced with the absolute path set using the --log-bin option. An absolute path recorded in the binary log index file remains unchanged; in such a case, the index file must be edited manually to enable a new path or paths to be used. The binary log file base name and any specified path are available as the log_bin_basename system variable.

只摘录了一部分,更全面的内容可到官网查看

导入大数据到表

向数据库中插入3万条数据

单个插入数据

如果每个数据单独插入,效率很低,每个插入都产生一个事务,写入效率低

批量插入数据

  • 每1000条插入一次,只产生一个事件,降低了事务的生成,提高了效率

  • 具体方法

    1. 把多条插入语句拼成一条

    2. 手动开启一个事务,在插入1000条数据后,提交事务。

      这样做可以减少binlog的生成次数,但redolog不一定减少

批量 vs 单个插入

  • 单个插入效率很低,30 * 1000 条记录用时 1分钟

  • 批量插入, 每1000条插入一次,效率很高,用时7.99秒

    5.54s user 0.54s system 77% cpu 7.799 total

    5.38s user 0.48s system 78% cpu 7.452 total

总结

插入大量数据时,应减少事务的提交,让多个插入在一个事务中完成,从而提高插入数据的效率

测试代码

class ImportTradelog
  def self.import(date)
    # 导入30天的数据
    30.times do |offset|
      datas = init_data(date + (60 * 60 * 24) * offset)
      puts datas

      # 批量插入, 每1000条插入一次,效率很高,用时7.99秒
      # 5.54s user 0.54s system 77% cpu 7.799 total
      # 5.38s user 0.48s system 78% cpu 7.452 total
      Tradelog.bulk_insert set_size: 1000, values: datas
    end
  end

  # 每天导入1000条数据
  def self.init_data(day)
    datas = []
    1000.times do |index|
      # 插入效率很低,30 * 1000 条记录用时 1分钟
      # date = {tradeid: tradeid, operator: operator, t_modified: t_modified}
      # Tradelog.create(date)
      datas << {
        tradeid: "#{day.strftime('%Y%m%d')}#{format('%04d', (index + 1))}",
        operator: rand(50),
        t_modified: (day + 60 * index)
      }
    end

    datas
  end
end

无意间发现 HexoNext 主题也很好看,之前的 Yelee 主题使用了好久,决定换成 Next。在配置过程中遇到不少问题,主要有两点值得分享:

  • 不要直接在主题配置文件上进行修改
  • 修改RSS显示位置使其在首页显示

配置主题文件

根据 Hexo 官方的推荐,不要直接修改主题的配置文件

The file should be placed in your site folder, both yml and json are supported. theme inside _config.yml must be configured for Hexo to read _config.[theme].yml

根据推荐执行以下操作:

  1. 配置主题为 Next 主题
# _config.yml
theme: "next"
  1. 在 site 根目录新建 _config.next.yml文件

    touch _config.next.yml
  2. 打开 theme/next/_config.yml把需要修改的选项 copy 到 _config.next.yml

    # _config.next.yml
    # 设置网站图标
    favicon:
      small: /favicon.ico
      medium: /favicon.ico
      apple_touch_icon: /apple-touch-icon.png
      safari_pinned_tab: /apple-touch-icon.png
  3. hexo启动时,会自动合并 _config.next.ymltheme/next/_config.yml 的设置内容,从而达到配置主题的作用。

不直接修改theme/next/_config.yml的好处是,当拉取新的更新时,不会因修改了_config.yml而发生冲突。(每个主题都是一个独立的 git项目)

修改RSS显示位置

看到网上说Rss的显示位置由首页侧边栏的位置移动到了每篇文章的最底部,这显然是不适合的,因为订阅不是按文章订阅,而是直接在首页中订阅。

自定义RSS到侧边栏:请先确认已经安装 hexo-generator-feed插件

  1. 删除文章底部的Rss(整个 follow me 设置都删除)
# theme/next/layout/_macro/post.njk

# 删除以下代码
{%- if theme.follow_me %}
  {{ partial('_partials/post/post-followme.njk', {}, {cache: theme.cache.enable}) }}
{%- endif %}
  1. 修改 Rss 样式

    # theme/next/layout/_partials/post/post-followme.njk
    
    <div class="followme"> # 修改为 <div class="">
      <span>{{ __('follow_me.welcome') }}</span> # 删除这一行
      <div class="social-list"> # #修改为 <div class="">
      # 省略部分源码
  2. 添加 Rss 到侧边栏(其实就是整个的 follwe me)

    # theme/next/layout/_partials/sidebar/site-overview.njk
    {%- if theme.follow_me %}
      {{ partial('_partials/post/post-followme.njk', {}, {cache: theme.cache.enable}) }}
    {%- endif %}
  3. 在站点配置文件中打开 Rss 设置

    # _config.yml
    follow_me:
      RSS: /rss2.xml || fa fa-rss
  4. 重启站点即可,就可以看到 Rss 显示在侧边栏了

常用的应用场景

  1. 合并提交

  2. 去除不要的提交

实际应用

场景1,合并多个提交

有 A B C D E F 6个提交,当前分支develop的最新提交为F,C D E F都是某一功能的持续提交,现需要把C到F的commit合并成一个commit,去除多余提交

  1. 方法一: git reset
git reset B --soft
git ci -m "merge C to F"
  1. 方法二: git rebase
git rebase --onto B C^ develop

场景2,去掉D提交

此时,git reset已经不再适合这个场景

使用git rebase

git rebase --onto C E^ develop

后记

  1. git rebase 语法

git rebase --onto <onbase> <since> <till>
git rebase --onto <onbase> <since>
git rebase <since> <till>
git rebase <since>
git rebase -i

onbase为要架接到的commit, since表示不包括自身到till的所有提交

git rebase --continue # 解决冲突后使用,以完成rebase
git rebase --skip # 跳过当前commit,进行下一个commit的合并
git rebase --abort # 放弃此次操作,还原工作区

  1. git rebase的莫名冲突

对于场景二: 使用git rebase可能出现冲突(感觉不应该出现冲突的,对此不是很理解,难道是因为丢弃D后使查找链C-D-E-F断裂造成git认为这两个commit需要合并,是因为E无法知道C是它的祖先吗)

在解决冲突后,使用git rebase --continue完成rebase操作

在git stash 中使用–index 恢复暂存区

git stash pop --index

Your branch is up-to-date with 'origin/develop'.
Changes to be committed: (use "git reset HEAD <file>..." to unstage)

modified:   metaprogramming/blocks/block_args.rb

Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified:   metaprogramming/blocks/block_args.rb
modified:   metaprogramming/blocks/block_binding.rb

git cat-file type选项和-p选项的区别
git cat-file 查看对象内容
git cat-file [commit | blob | tree | tag] <object> 可以用来查看一个对象的内容,但要求object一定要和[commit | blob | tree | tag]相匹配

可以使用一个通用的option: -p
git cat-file -p object来搞定,这样就不用区分object的类型了

PS:不太明白为什么要提供 [commit | blob | tree | tag] ,它和-p的区别是什么

git ls-files 显示暂存区目录树

如果一个删除的文件已经git add到暂存区,则暂存区的目录树不会包含这个文件,这也证明了暂存区有着自己的目录树

可以用git write-tree 为暂存区生成tree对象,以便可以用ls-tree对暂存区进行查看

执行

git write-tree
git ls_tree <git write-tree 的输出>

当对一个已经添加到暂存区的文件进行撤销
git add file
然后进行撤销
git reset HEAD -- file
这时,暂存区中没有任何被添加的文件
如果把某个历史提交(非HEAD指向的提示)中的 file添加到暂存区
git reset commit -- file
暂存区中则会显示file文件已经被加入,并且合本地文件不同

思考

如果把HEAD对应的文件放入暂存区,是否因为文件是HEAD中的,所以暂存区认为文件已经提交过了,所以没有已添加,待提交的提示。

而其它非HEAD中的文件则认为是还没有提交的,所以显示为已添加,待提交。

试验:

如果历史提交中的file文件内容与工作区中的file文件内容一样,执行
git reset commit -- file
则暂存区应该显示已添加,待提交的提示,但不会显示与本地有差异。

git可以自动进行文件合并

情况1 :文件A在第一次提交成功后,分别被A用户和B用户编辑后提交,A用户pull B用户的提交,这时,git判断两个文件是否冲突,如果不冲突则进行合并

情况2 :文件A在第一次提交成功后,B用户对其进行了编辑提交,A用户没有对文件做出任何修改,pull B用户的提交,这时,git会自动用B用户的修改去覆盖A用户的文件,即使A文件同一行的内容不同

思考:git是如何判断什么情况可以直接进行覆盖,什么情况需要进行合并。