Blog

时间戳和追溯点

Content #

时间戳:dfn[u]表示节点u深度优先遍历的序号。追溯点:low[u]表示节点u及其后代所能追溯到的最早(最先被发现)祖先点v的 dfn[v]值,即 \[\begin{diplaymath*} \text{low}[u] = \min_{(u,s),(u,w) \in E}\{\text{dfn}[u], \text{low}[s], \text{dfn}[w]\} \end{displaymath*} \]

其中s是u的儿子,(u, w)是反向边B.

low[u]计算步骤: \[\begin{displaymath*} \text{low}[u] = \begin{cases} \text{dfn}[u] \\ \min\{\text{low}[u], \text{dfn}[w]\} \\ \min\{\text{low}[u],\text{low}[s]\} \end{cases} \end{displaymath*}\]

From #

《算法训练营入门篇》 陈小玉

树上倍增法

Content #

F[i, j]表示 i 的 2^j 辈祖先,即 i 节点向根节点走 2^j 步到达的节点。可以分两个步骤:

  1. i 节点先向根节点走 2^(j-1) 步得到 F[i, j-1];
  2. 再从 F[i, j-1]节点出发向根节点走 2^(j-1) 步,得到 F[F[i, j-1], j-1],该节点为 F[i, j]。

递推公式:

F[i,j] = F[F[i,j-1], j-1], i=1,2,...,n, j=0,1,2,...,k, 2^k<=n, k=log2(n)

算法实现 #

void st_create() {
  for (int j = 1; j <= k; j++)
    for (int i = 1; i <= n; i++)
      F[i][j] = F[F[i][j - 1]][j - 1]
}

int lca_st_query(int x, int y) {
  if (d(x) > d(y)) { //保证x的深度小于或等于y的深度
    swap(x, y);
  }
  for (int i = k; i >= 0; i--)
    if (d(F[y][i]) >= d(x))
      y = F[y][i];
  if (x == y)
    return x;
  for (int i = k; i >= 0; i--)
    if (F[x][i] != F[y][i])
      x = F[x][i], y = F[y][i];
  return F[x][0];
}

From #

《算法训练营进阶篇》 陈小玉

...

LCA(Lowest Common Ancestors, 最近公共祖先)

Content #

u 和 v 的公共祖先指一个节点既是 u 的祖先,又是 v 的祖先。u 和 v 的最近公共祖先指距离 u 和 v 最近的公共祖先。若 v 是 u 的祖先,则 u 和 v 的最近公共祖先是 v。

树上任意两点之间的距离(用 LCA 求解):

dist[u]+dist[v]-2×dist[lca]。

求解LCA的算法 #

暴力搜索法 #

  1. 向上标记法

从 u 向上一直到根节点,标记所有经过的节点;若 v 已被标记,则 v 节点为 LCA(u, v);否则 v 也向上走,第 1 次遇到已标记的节点时,该节点为 LCA(u, v)。

  1. 同步前进法

将 u、v 中较深的节点向上走到和深度较浅的节点同一深度,然后两个点一起向上走,直到走到同一个节点,该节点就是 u、v 的最近公共祖先,记作 LCA(u,v)。若较深的节点 u 到达 v 的同一深度时,那个节点正好是 v,则 v 节点为 LCA(u, v)。

树上倍增法 #

From #

《算法训练营进阶篇》 陈小玉

...

RMQ(Range Minimum/Maximum Query,区间最值查询)

Content #

RMQ(区间最值查询)问题有多种解决方法,用线段树和 ST 解决 RMQ 问题的对比如下:

  1. 线段树预处理的时间为 O(nlogn),查询的时间为 O(logn),支持在线修改;
  2. ST 预处理的时间为 O(nlogn),查询的时间为 O(1),不支持在线修改。

线段树构建时,下标为0的元素是否使用,对计算孩子节点的坐标会有影响。以0开始,则: lchild = 2 * k + 1; rchild = 2 * k + 2; 线段树以1开始: lchild = 2 * k; rchild = 2 * k + 1;

From #

线段树的适用条件、抽象代数表示和C++模板

Restore Point

Content #

  1. 创建Restore Point
CREATE RESTORE POINT restore_point_name GUARANTEE FLASHBACK DATABASE;

使用GUARANTEE FLASHBACK DATABASE选项可以确保即使发生介质故障,也可以恢复到这个Restore Point。

select name, scn from v$restore_point;
  1. 恢复到Restore Point
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
FLASHBACK DATABASE TO RESTORE POINT restore_point_name;
ALTER DATABASE OPEN RESETLOGS;

RESETLOGS选项用于重置联机重做日志的序列号。

  1. 删除 Restore Point

    DROP RESTORE POINT restore_point_name;
    

Flashback技术的局限性

Content #

Flashback技术的局限性包括:

  1. Flashback Database 不能解决Media Failure, 这种错误RMAN恢复仍是唯一选择。
  2. 如果删除了数据文件或者利用Shrink技术缩小数据文件大小,这时不能用 Flashback Database技术回退到改变之前的状态,这时候就必须先利用RMAN 把删除之前或者缩小之前的文件备份restore 出来, 然后利用Flashback Database 执行剩下的Flashback Datbase。
  3. 如果控制文件是从备份中恢复出来的,或者是重建的控制文件,也不能使用 Flashback Database。
  4. 使用Flashback Database锁能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN。

From #

Flashback in Oracle

FLASHBACK #

Flashback Database 整个架构包括:

  1. Recover Writer(RVWR)后台进程
  2. Flashback Database Log日志
  3. Flash Recovery Area

一旦数据库启用了Flashback Database, 则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log,这些日志包括的是数据块的"前镜像(before image)", 这也是Flashback Database 技术不完全恢复块的原因。

Flashback技术的局限性

查看当前模式 #

SELECT name,flashback_on FROM V$DATABASE;

启用FLASHBACK模式 #

  1. 设定以下参数
alter system set db_recovery_file_dest='C:/oracle/product/10.2.0/flash_recovery_area' scope=both;
alter system set db_recovery_file_dest_size = 10G scope=both;

10G的容量偏少,如果这个空间用完,数据库会无法访问,在该值改好前,也无法关闭数据库。

alter system set db_flashback_retention_target = 1440 scope=both;
  1. 重启数据库到mount状态,执行下面的命令
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;

相关视图 #

  1. V$FLASH_RECOVERY_AREA_USAGE
  2. V$FLASHBACK_DATABASE_LOG Flashback Database所能回退到的最早时间,取决于保留的Flashback Database Log 的多少。
  3. V$FLASHBACK_DATABASE_STAT

对Flashback log空间情况进行更细粒度的记录和估计。这个视图以小时为单位记录数据库的活动量, Flashback_Data 代表Flashback log产生数量, DB_Data代表数据改变数量, Redo_Data代表日志数量,通过这3个数量可以反映出数据的活动特点,更准确的预计Flash Recovery Area的空间需求。

...

关闭Oracle数据库的四种方式

Oracle的关闭 #

  1. IMMEDIATE
  2. 会发生的事情:
    • 新用户不能登陆数据库
    • 未提交的事务会回滚
    • 不等待用户退出数据库
  3. 特点:
    • 不需要实例恢复,最安全,比较慢
  4. ABORT
  5. 会发生的事情:
    • 不允许新的连接和新的事务
    • 客户端的SQL语句立刻中止
    • 未提交的事务不回滚
    • 立刻中止所有连接
  6. 特点:
    • 只有数据库出问题,才使用这种方式
    • 最不安全的方式,重启后需要实例恢复
    • 最快
  7. NORMAL
  8. 会发生的事情:
    • 允许新的用户登录数据库
    • 要等所有用户退出数据库后,再关闭数据库
  9. 特点:常常不能关闭数据库,最慢的方式
  10. TRANSACTIONAL
  11. 会发生的事情:
    • 不允许新的用户登录数据库
    • 不允许创建新的事情
    • 所有事务完成后才关闭数据库
    • 用户在执行完手里的事务后,会被强制断开与数据库的连接
  12. 特点:
    • 不会使用客户端丢失数据
    • 不需要实例恢复
    • 比较慢

From #

重要参数(Oracle)

重要的参数 #

  1. 警报文件(Alert Log)相关 BACKGROUND_DUMP_DEST 警报文件位置
  2. 跟踪文件(Trace Log)相关 DIAGNOSTIC_DEST 后台进程(background processes)相关的信息 USER_DUMP_DEST 服务器进程(server processes)相关信息 MAX_DUMP_FILE_SIZE 限制跟踪文件的大小 MAX_DUMP_FILE_SIZE={ integer [K|M] | UNLIMITED }

From #