「GRUB」- 引导加载程序

在系统启动的第二步中,开始执行引导程序,那引导程序是哪里来的呢?引导程序是GRUB安装到MBR中。
GRUB,一个引导加载程序,属于GNU项目。它是「多引导规范」的「参考实现」,可以用户在安装了多个操作系统的主机上选择要启动的系统,或者选择特定的内核配置。
引导加载程序的任务
任务一、识别文件系统
操作系统的内核通常保存在文件系统中的,但是BIOS并没有文件系统的概念,因此BIOS无法直接启动内核。因此需要加入中间层,系统启动的大概为 BIOS -> BOOTLOADER -> KERNEL。因此在基于BIOS的系统中,读取文件系统的文件由 BOOTLOADER 负责。由引导加载程序加载内核到内存执行。这有两种途径:

途径一,直接读取物理扇区:不管用什么文件系统,数据在磁盘上还是数据。所以,只要找到保存文件的扇区,将扇区依照顺序拼凑起来,即使不理解文件系统,也能够获取到文件。鉴于此,定义一个“间接层”,该层保存了内核所在的物理扇区,引导程序直接读取这个间接层来获取内核,这样就可以了。但是,这也带来了一些问题。内核文件不能动,移动、碎片整理、更新内核都会导致物理扇区发生变化。一旦变化,就要重新更新”间接层“,同时可能还要更新MBR中的代码(因为它要知道间接层的开始和结束位置)。这个方案不好。

途径二,理解文件系统:让引导程序理解文件系统,这样就可以通过文件路径找到内核。这就要求引导程序中包含某些驱动程序,以识别文件系统。这种方法减少了对物理扇区的依赖,并且在内核文件发生修改之后,不需要更新引导程序。并且,由于可以理解文件系统,引导程序的配置文件可以保存在文件系统中。但是也存在一些缺点,这种途径增加了引导加载程序的大小和复杂性。

我们使用的GRUB就是第二种途径,通过理解底层的文件系统。引导加载程序也被分成了多个阶段,以适合MBR引导方案。目前GRUB由两个版本,GRUB Legacy(存在于旧的发行版中)与GRUB 2(从头开始开发,意图替换之前的版本)。目前GRUB 2已经在大多数Linux发行版中使用。
任务二、多阶段执行
在主引导记录中,留给引导程序的空间只有434到446字节。对于简单的引导程序,这个空间足够了。对于相对复杂的引导,这个空间是远远不足的。因此复杂的引导程序只能被分为两部分:一部分位于主引导记录中,一部分位于其他位置。由主引导记录中的引导程序加载另一部分引导程序。
第一版 – GRUB Legacy
该版本采用两阶段方法。包含在MBR中的是第一阶段(或者包含一个标准的MBR实现,然后从活动「分区的引导扇区」中加载第一阶段)。由于大小的限制,第一阶段只能从磁盘的固定位置加载几个扇区,来加载下一阶段的引导程序。
阶段[……]

READ MORE

「GRUB」- 在BIOS系统上的GRUB引导

问题描述
本文分为两部分: 1)BIOS + MBR + GRUB 2)BIOS + GPT + GRUB
这两种模式下有所区别,下面会一层层的解释这两种方式。通常GPT与UEFI一起使用,因为UEFI只能使用GPT分区表,GPT是UEFI的一部分,但是本文本文讨论的是GPT + BIOS的方式,目前并不涉及UEFI相关的内容。
启动原理简述
GRUB由几个镜像文件组成,其中最重要的是: 1)# boot.img,此图像是GRUB的第一部分。 由于大小限制,它不了解文件系统。它的唯一功能是从本地磁盘加载core.img文件。要使BIOS读取它,此镜像将写入MBR中或分区的引导扇区。 2)# core.img,它包含足够的模块来访问/boot/grub目录,并在运行时从文件系统加载其他所有内容(包括菜单处理,加载目标操作系统的能力等)。此镜像可以安装在磁盘上的不同区域,具体取决于是使用MBR分区表还是GPT分区表。
所以,就引导来说,这两种模式的主要区别还是在与core.img的位置。
BIOS + MBR + GRUB
有两个位置用来安装core.img镜像:
# 在MBR后的“空隙”中:“空隙”是MBR和第一个分区之间的区域。由于MBR是512字节,并且第一个分区通常以1MiB(2048个扇区)偏移对齐,因此为core.img留下了足够的空间。
# 在文件系统中,在这种情况下,包含core.img的块列表可以存储在该分区的第一扇区中。需要注意的是,这些块可能会被文件系统移动。 因此,不建议在此处放置core.img镜像。
# BIOS + GPT + GRUB
可以在GPT磁盘上为GRUB保留整个分区,称为「BIOS引导分区」。然后,可以将GRUB嵌入到该分区中,而不会被其他软件覆盖,也不会被包含在可能移动其块的文件系统中。
BIOS引导分区的大小至少应为31KiB。在扇区大小为512字节的GPT磁盘上,第一个可用扇区通常为34。因为: 1)LBA 0: Protective MBR. 2)LBA 1: GPT header. 3)LBA 2-33: Partition Entry Array.
并且第一个分区通常以1MiB(2048个扇区)偏移对齐。这留下了类似于MBR磁盘上的间隙,可以将它作为「BIOS引导分区」使用。 但是,也可以在磁盘上的不同偏移处创建「BIOS引导分区」。
「BIOS引导分区」还必须具有正确的分区类型,即在gdisk中设置为EF02,或者在parted中设置bios_grub标志。这也是下面错误的原因:

# grub-install /dev/sdd
Installing for i386-pc platform.
gr[……]

READ MORE

「Linux Boot Process and Shutdown」- Boot loader Stage 2(GRUB Boot loader)

显示可选择菜单
然后,启动加载器会根据配置文件,向用户显示可选择菜单,来提供可选择的启动项。

值得注意的是,虽然该菜单是 /boot/grub/grub.cfg 定义的,但是 GRUB 在显示该菜单的时候,并不是读取 /boot/grub/grub.cfg 文件。
用户选择启动项
概述:当用户选择启动项后,根据启动项配置,Bootloader 会从磁盘加载配置的 kernel、initramfs 镜像,并载入内存中。
如下截取自 /boot/grub/grub.cfg 配置,是第一个菜单项的内容:

menuentry ‘Ubuntu’ –class ubuntu –class gnu-linux –class gnu –class os $menuentry_id_option ‘gnulinux-simple-02a38d2f-1340-452f-ba82-79ffbe8498ce’ {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
set root=’hd0,gpt2′
if [ x$feature_platform_search_hint = xy ]; then
search –no-floppy –fs-uuid –set=root –hint-bios=hd0,gpt2 –hint-efi=hd0,gpt2 –hint-baremetal=ahci0,gpt2 f2999e53-cb52-46ab-b419-c27f4cdd1134
else
search –no-floppy –fs-uuid –set=root f2999e53-cb52-46ab-b419-c27f4cdd1134
fi
linux /vmlinuz-5.4.0-84-generic root=/dev/mapper/ubuntu–vg-ubuntu–lv ro maybe-ubiquity
initrd /initrd.img-5.4.0-84-generic
}

当用户选择该菜单后,GRUB 将执行该菜单中定义内容(即花括号内的指令)。
在这些指令中,对[……]

READ MORE

「Linux Boot Process and Shutdown」- Kernel and Initramfs

内核的任务
内核接管所有操作系统进程,比如内存管理、任务调度、读入/写出、进程通信,以及整个系统的控制。
启动阶段
这分为两个阶段加载:
第一阶段,内核被载入内存并解压,并设置某些基本功能(如内存管理)。
第二阶段,控制权切换到主要的内核启动进程。一旦内核完全运作,内核便开始查找并运行初始化进程(init),分别设置用户空间、用户环境需要的进程、最后的登录界面。然后内核本身被允许进入空闲状态,受到来自其他进程的调用。
在某些平台上(比如ARM 64位),内核解压必须由引导加载程序完成。
第一阶段,内核加载
内核通常作为镜像文件被加载,使用zlib压缩为zImage或bzImage格式。
在内核头部的小段例程设置系统函数、进行最少的硬件初始化(例如重要的硬件和内存页)
解压镜像到高位内存,
并留意已配置RAM驱动器。
然后通过./arch/i386/boot/head与startup_32()进程执行内核启动。
第二阶段、内核启动
内核启动函数(swapper,process 0)建立内存管理(页表、内存页)、检测处理器类型及其附加功能(比如浮点处理),
然后调用start_kernel()切换到非特定架构内核功能,由start_kernel()执行范围广泛的初始化功能(终端,剩余内存管理,设备与驱动初始化)。它设置中断处理(IRQ),进一步配置内存,启动初始化进程(首个用户空间进程),通过cpu_idle()启动空闲任务。
值得注意的是,内核启动进程还会挂载initrd,它是作为临时根文件系统在启动阶段以前加载。initrd允许直接从内存中加载驱动模块,而不需要依赖其他设备(比如磁盘)及访问这些设备所需要的驱动(比如SATA驱动)。分离某些静态编译到内核的驱动,并且其他驱动从initrd加载,这允许内核更小。稍后通过pivot_root()切换文件系统,它卸载临时文件系统,并使用真正的文件系统替代(只要能够访问)。由临时文件系统使用的内存将会被回收。
因此,内核初始化设备,只读挂载由引导加载程序指定的根文件系统,然后运行初始进程(/sbin/init,PID=1)。当挂载文件系统时,通过内核打印消息,当启动初始进程时,通过初始化打印消息。在根文件系统挂载前,它还可以任选地运行initrd以允许进行设置,并处理设备相关的事情(RAM磁盘或类似东西)
根据RED HAT描述,因此在此阶段的详细内核进程可以概括如下:

在内核被加载后,(1)它立即初始化并配置计算机内存,并配置连接到系统的各种硬件(处理器,读写子系统,存储设备)。(2)然后在内存预定的位置查找压缩的initrd镜像,解压,挂载,加载驱动。(3)接下来[……]

READ MORE

「Linux Kernel」- initrd(initial ram disk),initramfs(initial RAM file system)

问题描述
该笔记将记录:与 initrd、initramfs 相关的内容。
解决方案
技术的诞生是为了解决问题。
如果把所有的内核模块(驱动)都编译到内核中,将增加内核的大小,载入时将消耗等多内存,加载速度变慢,设置还会出现其他不确定性问题。
还有很多更复杂的场景,比如需要从 Software RAID、LVM、NFS 中加载系统盘,这些特殊情况如果都加到内核中,对内核来说将是场灾难。
initrd, inital ram disk
initrd,为此而生
它是个文件系统,很多发行版使用 ext2 格式, 其中包含各种内核模块及某些特殊功能代码; Bootloader 将其加载到内存,Kernel 将其解压到内存中,并将其作为文件系统挂载,以从中获取或执行必要文件。 Kernel 为了识别 initrd 这个文件系统,需要相关的驱动(中间文件系统驱动)。
查看 initrd 内容:linux – Why is it that my initrd only has one directory, namely, ‘kernel’? – Unix & Linux Stack Exchange
initramfs, initial RAM file system
initramfs,initial RAM file system,是 initrd(Initial Ramdisk)的接替者,since Kernel 2.5.46(自 Linux 2.6.13 起可用)。
这个镜像包含初始文件系统,是经过 gzip 的 cpio 归档(可选压缩),其中包含在启动时所有必要硬件的内核模块、初始化脚本、块驱动等等等等。 initramfs 包含在内核镜像(vmlinuz)中,Kernel 将归档文件解压到特殊的 tmpfs 实例中,该实例成为初始 root file system。
对比 initrd 方式,该方式的优点: 1)不需要将中间文件系统驱动编译到内核:initramfs 是 CPIO 格式,直接解压到在 tmpfs 上,而 tmpfs 在内核上,不需要单独文件系统驱动来访问。 2)不需要将块驱动编译到内核:其实当 Kernel 加载到内存并开始运行后,操作系统便已开始运行。至于运行应用程序服务,那是用户空间的事情,也就说从 HDD 还是 NFS 启动那是用户空间的工作,由用户空间自行实现即可,内核不再关心这些块驱动。
在 RHEL 7 中,initramfs 包含自身可用的整个系统。dracut,用来创建 initramfs 镜像。lsinitrd,用来查看 initramfs 镜像。
补充说明
出于历史原因,虽然很多 Linux 发行版中能够看[……]

READ MORE

「Linux Boot Process and Shutdown」- Init,systemd,runlevel,初始化进程

systemd 会查找从内核命令行传递或系统中配置的默认目标,然后启动单元,以符合目标的配置,从而解决单元之间的依赖问题。本质上systemd目标是一组应在激活后达到所需系统状态的单元。这些Target通常至少包含生成文本登录或图形登录的屏幕。
内核找到/sbin/init文件,开始执行,PID=1;
首先读取初始化文件,/etc/inittab,该文件指示init读取环境中的配置脚本,
按照运行级别启动服务与进程
参考文献
6 Stages of Linux Boot Process (Startup Sequence) Stages of Linux booting process – explanation, step by step tutorial[……]

READ MORE

「系统启动」- RUNLEVEL

Stage 6: User prompt
This is actually not part of booting process but thought of including it here for better understating. Once the Kernel get the control it start multiple instances of “getty” which wait’s for console logins which spawn one’s user shell process and gives you user prompt to login. In our next post we will see different prompts available in Linux/Unix.
参考文献
6 Stages of Linux Boot Process (Startup Sequence) Stages of Linux booting process – explanation, step by step tutorial[……]

READ MORE

「MS-DOS」- Microsoft Disk Operating System

显示缓冲区的结构
80×25 彩色字符模式显示缓冲区(以下简称为显示缓冲区)的结构:
显示缓冲区的空间
在内存地址空间中,B8000H~BFFFFH,共 32KB 的空间,为 80X25 彩色字符模式的显示缓冲区。向这个地址空间写入数据,写入的内容将立即出现在显示器上;
在 80×25 彩色字符模式下,一个字符在显示缓冲区中占两个字节,分别存放字符的 ASCII 码 和 属性,每个字符可以有 256 种属性(背景色、前景色、闪烁、高亮等组合信息);
显示器可以显示 25 行,每行 80 个字符。
在 80×25 模式下,显示缓冲区分为 8 页,每页 4KB(≈4000B),一屏的内容在显示缓冲区中共占 4000 个字节,显示器可以显示任意一页的内容。 一般情况下,显示第 0 页的内容。也就是说通常情况下,在 B8000H-B8F9FH 中的 4000 个字节的内容将出现在显示器上。
在一页显示缓冲区中: 偏移 000~09F 对应显示器上的第 1 行(80 个字符占 160 个字节); 偏移 0A0~13F 对应显示器上的第 2 行; 偏移 140~1DF 对应显示器上的第 3 行; 依此类推,可知,偏移 F00~F9F 对应显示器上的第 25 行。
字符的属性
在显示缓冲区中,偶地址存放字符,奇地址存放字符的颜色属性。
一个在屏幕上显示的字符,具有前景(字符色)和背景(底色)两种颜色,字符还可以以高亮度和闪烁的方式显示。前景色、背景色、闪烁、高亮等信息被记录在属性字节中。
属性字节的格式:

| 7 | 6 5 4 | 3 | 2 1 0 |
| BL | R G B | I | R G B |
| 闪烁 | 背景 | 高亮 | 前景 |

参考文献
Wikipedia/MS-DOS[……]

READ MORE

「Computer Sciense」- Concurrency, Parallelism, and Distributed Systems

章节列表
「Distributed Systems」- Concurrency Control 「Distributed Systems」- 数据复制 「Distributed Systems」- Leader Election 「Distributed Systems」- Liveness Detection[……]

READ MORE

「Distributed Systems」- Liveness Detection

实现活性检测主要有两种方案: 1)被动检测:通过探测节点周期检测 Leader 节点,看是否健康,比如 Redis Sentinel 等等; 2)主动上报:Leader 节点可定期向协调服务发送”特殊心跳”汇报健康状态,若其未正常发送心跳,并超过和协调服务约定的最大存活时间后,就会被协调服务移除 Leader 身份标识。同时其他节点可通过协调服务,快速感知到 Leader 故障,进而发起新的选举;[……]

READ MORE

「Distributed Systems」- 数据复制

问题描述
传统的单副本存在单点故障;
解决方案
为了解决单点故障问题,软件系统工程师引入数据复制技术(多副本);
通过数据复制方案: 1)提高服务可用性,避免单点故障。 2)提升读吞吐量、甚至就近部署在业务所在的地理位置,降低访问延迟。
原理简述
多副本常用的技术方案主要有:主从复制;去中心化复制;
主从复制
主从复制,比如 MySQL/Redis 单机主备版就基于主从复制实现的,
其又分为全同步复制、异步复制、半同步复制:

全同步复制,指主收到一个写请求后,必须等待全部从节点确认返回后,才能返回给客户端成功。因此如果一个从节点故障,整个系统就会不可用。这种方案为了保证多副本的一致性,而牺牲了可用性,一般使用不多。

异步复制,指主收到一个写请求后,可及时返回给 client,异步将请求转发给各个副本,若还未将请求转发到副本前就故障了,则可能导致数据丢失,但是可用性是最高的。

半同步复制,介于前两者之间,它是指主收到一个写请求后,至少有一个副本接收数据后,就可以返回给客户端成功,在数据一致性、可用性上实现了平衡和取舍。

去中心化复制
去中心化复制,它是指在一个 n 副本节点集群中,任意节点都可接受写请求,但一个成功的写入需要 w 个节点确认,读取也必须查询至少 r 个节点。
你可以根据实际业务场景对数据一致性的敏感度,设置合适 w/r 参数。比如你希望每次写入后,任意 client 都能读取到新值,如果 n 是 3 个副本,你可以将 w 和 r 设置为 2,这样当你读两个节点时候,必有一个节点含有最近写入的新值,这种读我们称之为法定票数读(quorum read)。
AWS 的 Dynamo 系统就是基于去中心化的复制算法实现的。它的优点是节点角色都是平等的,降低运维复杂度,可用性更高。但是缺陷是去中心化复制,势必会导致各种写入冲突,业务需要关注冲突处理。
参考文献
etcd 实战课(唐聪,腾讯云资深工程师,etcd 活跃贡献者)_极客时间[……]

READ MORE

「DSA」- 杂记

漫画:经典谷歌面试题“扔鸡蛋”,看看你会做吗? https://mp.weixin.qq.com/s/NugGnNX4Vv3SNhQrmzjF-A
在近三天内修改的文章随机排序:MODIFY_DATE + RAND() * 4
算法复杂度(Algorithmic complexity)
什么是算法复杂度_icolakele的博客-CSDN博客_算法的复杂度
就是衡量程序执行效率的度量方法。衡量算法的好坏,不仅要看程序执行所需的时间,还要看程序用到的计算资源,比如内存资源。
事实上,算法复杂度包括时间复杂度(Time complexity)和空间复杂度(Space complexity)。我们平时说的算法复杂度,一般都是在说算法的时间复杂度。
时间复杂度
理论上讲,程序执行消耗的时间是无法事先估算的,那如何计算时间复杂度呢?换个思路,程序执行时必然有一定的步骤,不防假设执行每个步骤所需要的时间为t,t具体是什么值并不重要,然后只需要计算一个程序执行所需要的步骤,最终以步骤数来衡量算法时间复杂度。
理论上讲,程序执行消耗的时间是无法事先估算的,那如何计算时间复杂度呢?换个思路,程序执行时必然有一定的步骤,不防假设执行每个步骤所需要的时间为t,t具体是什么值并不重要,然后只需要计算一个程序执行所需要的步骤,最终以步骤数来衡量算法时间复杂度。
举个例子,计算1+2的复杂度是多少呢?
a = 1 b = 2 sum = a + b
一共有3个步骤,不防记作O(3),其实O(3) = O(1)。 计算正整数n的阶乘呢?
factorial = 1 for i = 1 to n factorial = i * factorial
第一行执行1次,第二行执行n次 ,第三行执行n次,一共执行2n + 1次。不防记作O(2n + 1)。其实O(2n + 1) = O(n)。
大 O 表示法
现在可以很自然的引入大O表示法了(Big O notation)。为什么用O呢?其实这里的O源自短语函数的阶数(Order of the function)。 如果还记得高数中等价无穷小和等价无穷大的概念的话,就很容易理解大O表示法了。
f(x) = 3×3 + 2x +10
不难理解,当x趋于∞时,对f(x)值变化影响最大的是x³,那么我们就可以说f(x)和x³是等价无穷大的。因此,常数次执行步骤的算法复杂度统称为O(1),这也是为什么前面我说O(3) = O(1)。类似的,O(2n + 1) = O(n)。 计算算法时间复杂度时,我们只需要关心对结果影响最大的那一项,也就是直接找到计算结果等价无穷大最简洁的表示方法。因此我们可以推导出O(f(x)) = O([……]

READ MORE

「DSA」- 一致性哈希(Consistent Hash)

问题描述
Hashing:将任意大小的数据映射到固定大小数据的过程;
Hash/Hash-Code:Hasing 操作后得到的固定大小的数据,通常是整数;
Hash-Function:用于将数据映射为 Hash 的函数; 两种 Hash-Function 用于不同目的:cryptographic;non-cryptographic;
Collision:碰撞,即两个不同的数据具有相同的 Hash-Code; 解决 Collision 的常用做法是:Chaining;Open Addressing;
Hash-Table/Hash-Map:是 CS 中常用的两种数据结构,其用于恒定时间查找;
Distributed Hashing:将多个 Hash 分布在多个不同的存储位置(比如服务器);
Rehashing:如果存储位置的数量发生变化,则需要重新计算所有 Hash 的存储位置;
Rehashing Problem:Rehasing 带来的问题便是大量 Hash 的存储位置发生变化;
解决方案
Consistent Hashing:是种特殊类型的哈希,其所使用的哈希函数随着散列函数范围的变化而变化最小。
Consistent Hashing 提供分布式方案,使其不依赖于存储位置的数量,这通过抽象环(Hash-Ring)来解决,这使得存储位置数量的变化不会影响整个系统;

顺时针:bob@example.com, mark@example.com on S2; smith@example.com, adam@example.com on S3; alex@example.com, john@example.com on S1;
S1, S2, S3 是三个存储位置,当 S3 消失后,其上的数据将被 S1 承载; 为了减轻 S1 压力,提出 Virtual-Node 概念:将 S3 分为多个 Virtual-Node,当 S3 消失后,其 Virtual-Node 上的数据将 S1、S2 承载; 该过程中,S1 S2 原有的 Hash-Code 无需重新计算,所以减少对整个系统的影响;
将如有 N 个存储位置,K 个 Key:如果移除某个存储位置,则仅会影响 K/N 个 Hash-Code(因为每个存储位置存储 K/N 个 Key,当该位置消失,则影响 K/N 个 Key)
参考文献
Consistent Hashing. Consistent hashing idea was introduced… | by Vivek Kumar Singh[……]

READ MORE

「Data Structures」- 数据结构

[……]

READ MORE

「Data Structures」- 环链(Linked List)

链表(Linked List)
单向链表(Singly linked list)

双向链表(Doubly Linked List)

循环链表(Circular Linked List)
单向循环列表(Circular Singly Linked List)

双向循环链表(Doubly Circular Linked List)

参考文献
Linked List | Set 1 (Introduction) – GeeksforGeeks Doubly Circular Linked List | Set 1 (Introduction and Insertion) – GeeksforGeeks[……]

READ MORE

「GPG – GNU Privacy Guard」

GnuPG是「OpenPGP标准」(由RFC4880定义)的完整实现。
GnuPG允许数据和通信进行加密及签名,具有多功能的密钥管理系统以及各种公共密钥目录的访问模块。 GnuPG也称为GPG,是一种命令行工具,具有与其他应用程序轻松集成的功能。具有丰富的前端应用程序和库可用。 GnuPG还提供对S/MIME和Secure Shell(ssh)的支持。
GnuPG is GNU’s tool for secure communication and data storage. It can be used to encrypt data and to create digital signatures. It includes an advanced key management facility and is compliant with the proposed OpenPGP Internet standard as described in RFC4880.
安装程序
BLFS1.10/GnuPG-2.1.15
通过仓库安装

#!/bin/bash

############################################################
# Kali GNU/Linux Rolling
############################################################
apt-get install gpg gunpg

通过源码安装
参考BLFS1.10/GnuPG-2.1.15:http://www.linuxfromscratch.org/blfs/view/7.10/postlfs/gnupg.html
安装的可执行程序
addgnupghome,is used to create and populate user’s ~/.gnupg directories applygnupgdefaults,is a wrapper script used to run gpgconf with the –apply-defaults parameter on all user’s GnuPG home directories. dirmngr,is a tool that takes care of accessing the OpenPGP keyservers. dirmngr-client,is a tool to contact a running dirmngr and test whether a certificate has been revoked. g13,is a tool to[……]

READ MORE

「BoltDB」- K/V Store(Go)

问题描述
在使用 Grafana Loki 服务时,其使用该 BoltDB 数据库,用于存储索引;
该笔记将记录:与 BoltDB 相关的内容,以及相关问题的解决办法;
解决方案
BoltDB,类似于 SQLite 数据库,以文件的方式存储数据,并不需要运行独立的数据库服务; 该项目已归档,其主要目的是提供轻量的 K/V 存储(现已实现),不提供更多附加的功能特性;
CoreOS/bbolt 提供是 Bolt 的 Fork,其提供更多的功能及特性。 CoreOS 开发 etcd 服务,而 etcd 使用 BoltDB,所以 CoreOS 才会 Fork BoltDB 吧;
参考文献
GitHub – boltdb/bolt: An embedded key/value database for Go. GitHub – etcd-io/bbolt: An embedded key/value database for Go.[……]

READ MORE

「BoltDB」- 概念、术语

boltdb,是个基于 B+tree 实现的 key-value 嵌入式数据库,其通过提供 Bucket(桶)机制,来实现类似 MySQL Table 的逻辑隔离;[……]

READ MORE

「BoltDB」- 文件布局

boltdb 文件指的是你 etcd 数据目录下的 member/snap/db 的文件, etcd 的 key-value、lease、meta、member、cluster、auth 等所有数据存储在其中;
etcd 启动的时候,会通过 mmap 机制将 db 文件映射到内存,后续可从内存中快速读取文件中的数据。写请求通过 fwrite 和 fdatasync 来写入、持久化数据到磁盘;

从图中的左边部分你可以看到,文件的内容由若干个 page 组成,一般情况下 page size 为 4KB;
page 按照功能可分为: 1)元数据页 (meta page):文件最开头的两个 page 是固定的 db 元数据 meta page, 2)B+ tree 索引节点页 (branch page):索引节点页保存了 B+ tree 的内部节点,如图中的右边部分所示,它们记录了 key 值, 3)B+ tree 叶子节点页 (leaf page):叶子节点页记录了 B+ tree 中的 key-value 和 bucket 数据; 4)空闲页管理页 (freelist page):空闲页管理页记录了 db 中哪些页是空闲、可使用的; 5)空闲页 (free page);
boltdb 逻辑上通过 B+ tree 来管理 branch page / leaf page, 实现快速查找、写入 key-value 数据;
boltdb API
那么如果要在 etcd 中执行一个 put 请求,boltdb 中是如何执行的呢? boltdb 作为一个库,提供了什么 API 给 client 访问写入数据?
boltdb 提供了非常简单的 API 给上层业务使用,当我们执行一个 put hello 为 world 命令时,boltdb 实际写入的 key 是版本号,value 为 mvccpb.KeyValue 结构体;
这里我们简化下,假设往 key bucket 写入一个 key 为 r94,value 为 world 的字符串,其核心代码如下:

// 打开 boltdb 文件,获取 db 对象
db,err := bolt.Open(“db”, 0600, nil)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 参数 true 表示创建一个写事务,false 读事务
tx,err := db.Begin(true)
if err != nil {
return err
}
defer tx.Rollback()
// 使用事务对象创建 key bucket
b,err := tx.CreatebucketIfNo[……]

READ MORE

「Memcached」

Memcached?
以下内容引自官网:

Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.

Memcached is simple yet powerful. Its simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages.

通过上面的简单介绍,可以发现一下几点:

高性能的内存对象缓存
Memcached通过减轻数据库负载的方式来加速动态web应用。
Memcached中保存的数据来自于数据库查询,API调用结果,页面渲染结果等,这些内容都属于可缓存的结果数据。

所以,我并不会将Memcached和Redis进行比较。
Memcache和Memcached的关系
Memcached Memcached,它是服务端的一个软件,d是daemon的意思。本文介绍的内容就是关于Memcached的。
Memcache 以PHP为例,Memcache就是一个PECL扩展,这个模块提供了一套方便的程序和面向对象的API(一共就18个方法,如果没数错),用于访问Memcached服务。 同时,PHP里面还有一个Memcached,这是一个PHP的扩展,但是这个扩展使用了libmemcached库,比Memcache功能更多、API更丰富(大约有50个方法)。
相关链接
#memcached on freenode
参考文献
Memcached Homepage Memcached Wiki[……]

READ MORE

「Memcached」- 安装

问题描述
该笔记将记录:在 CentOS 上,安装 Memcached 服务的方法,以及常见问题的解决方案。
服务安装
方法一、从源中安装(推荐)

# Debian/Ubuntu:
apt-get install memcached

# Redhat/Centos:
yum install memcached

方法二、使用源码安装
安装依赖库 可以「到官网」/「到Github仓库」下载libevent源码,然后编译安装。也可以从发行版的源中安装libevent库:

# Debian/Ubuntu:
apt-get install libevent-dev

# Redhat/Centos:
yum install libevent-devel

安装服务 参考 安装指示 文档:

#!/bin/sh

wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install

可执行程序
memcached 该服务的程序文件。
命令行选项
-s <file> 指定要监听的UNIX socket文件 (禁用了网络支持)。
-A 支持ASCII的shutdown命令。
-a <perms> 指出由-s选项创建的Unix Socket文件的权限。八进制格式。
-l <addr> 要监听的IP地址。可以是host:port的格式。如果没有指定port则会使用-p或者-U选项指定的值。 如果要指定多个地址,可以使用逗号分割,或者多次使用-l选项。为了避免安全问题和非法访问之类的情况,强烈建议绑定地址,或者使用防火墙。
-d 以守护进程的方式运行memcached服务。
-u <username> 当以root运行memcached时,可用此选项指定运行memcached的用户。
-m <num> memcached用于缓存Object而使用的内存的最大量。 默认64M。
-c <num> 最大的连接数。 默认1024。
-R <num> 该选项主要用于防止客户端“饿死”,通过限制从单个客户端连接中处理的顺序请求数量。 一旦连接超出了此值,在处理来自此连接的任何进一步请求之前,服务器将尝试处理其他连接上的I/O。 默认值为20
-k 锁定所有分页的内存。 在[……]

READ MORE

「Memcached」- 快速开始与基本概念

问题描述
该笔记将记录:与 Memcached 有关的基础操作以及基本概念。
通过 telnet(1) 命令访问 Memcached 服务
Memcached Telnet Commands Example Testing memcached with telnet
该部分将介绍如何通过 telnet(1) 命令访问 Memcached 服务,以进行一些基本操作(增删改查、状态查看)。
连接服务
telnet <host> <port>
添加键值(SET)
SET <KEY> <META_DATA> <EXPIRY_TIME> <LENGTH_IN_BYTES> [ENTER] <VALUE>
!!!唯一需要注意的地方是KEY与VALUE是分为两次输入的,第一次输入KEY,在回车之后,输入VALUE值。
获取键值(GET)
GET <KEY>
修改键值(REPLACE)
REPLACE <KEY> <META_DATA> <EXPIRY_TIME> <LENGTH_IN_BYTES> [ENTER] <VALUE>
!!!与SET指令类似,先输入KEY,在回车之后,输入VALUE值。
删除键值(DELETE)
DELETE <KEY>
查看状态(STATS)
STATS
退出 telnet(1) 命令
在连接成功后,会收到Escape character is ‘^]’.提示。
因此,按下Ctrl + [组合键,可以进入telnet(1)的命令模式,然后输入quit后,按下ENTER键即可。
libMemcached
libMemcached Homepage
libMemcached 开源的 C/C++库,用于访问 Memcached。PHP 安装 Memcached 扩展时,需要先安装这个库;[……]

READ MORE

「Memcached的管理」

telnet
可以使用telnet访问Memcached
memcache.php
PHP的Memcache扩展的源码包中有一个名为memcache.php的PHP文件。 具备如下特点:

支持GUI查看Memcachd的内存使用情况。
命中率、请求频率等等。
Slab的使用情况等。
支持删除ITEM,但是这个功能一般,不支持查找功能。

软件截图
MemAdmin
项目地址:https://github.com/junstor/memadmin 整个项目比较老了,依赖于PHP的Memcache扩展,不支持Memcached扩展。
MemcAdmin
https://github.com/rewi/memcadmin
Memcached Query GUI
https://sourceforge.net/projects/memcached-query-gui/
Memcached-GUI
https://github.com/mailopl/memcached-gui
FastoNoSQL
http://fastonosql.com/ https://github.com/fastogt/fastonosql
Keylord
https://protonail.com/products/keylord
参考文献
How to Monitor Memcached[……]

READ MORE

「SQL Server」- 安装

SQL Server and Ubuntu 16.04.3 LTS

#!/bin/sh

###########################################################################################
# 安装
###########################################################################################
curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add –
add-apt-repository “$(curl https://packages.microsoft.com/config/ubuntu/16.04/mssql-server-2017.list)”
apt-get update
apt-get install -y mssql-server

###########################################################################################
# 初始化并启动服务
###########################################################################################
/opt/mssql/bin/mssql-conf setup
systemctl enable mssql-server
systemctl start mssql-server
systemctl status mssql-server

# 手册文档安装的usr下,服务管理文件在lib下,SQL Server的服务程序文件在opt下。

Windows 7 and SQL Server 2012 Express
在Windows 7 Service Pack 1中,可以安装SQL Server 2014 Express版本。但是在Windows 7中,只能安装SQL Server 2012 Express版本。
Download Microsoft® SQL Server® 2012 Express from Official Microsoft Download Center
安装方法:下一步 => 下一步 => …………
相关链接
其他Linux发行版,安装参考官方「Try SQL Server on-premises or in the cloud」文档。 SQL Server Express Supp[……]

READ MORE

「SQL Server」- 杂记

Schema
SQL Server中“完整”的表名是“三段”的,例如TestData.dbo.Products,其中TestData是Database,dbo是Schema,Products是Table。
Schema是拥有该表的数据库对象。如果您是管理员,则dbo是默认Schema。dbo代表数据库所有者。
重命名
# 重命名列名
Rename Columns (Database Engine)
以下示例将Sales.SalesTerritory表中的TerritoryID列重命名为TerrID。执行如下SQL:
USE AdventureWorks2012;
GO
EXEC sp_rename ‘Sales.SalesTerritory.TerritoryID’, ‘TerrID’, ‘COLUMN’;
GO

# 重命名表名
USE AdventureWorks2012;
GO
EXEC sp_rename ‘Sales.SalesTerritory’, ‘SalesTerr’;

# 注意事项
无论是新的表名值,还是新的列名值,都不需要添加前缀。如下用法:
EXEC sp_rename ‘Sales.SalesTerritory’, ‘Sales.SalesTerr’;

会将“SalesTerritory”重命名为“Sales.SalesTerr”,因此可以说是错误的。
删除列
ALTER TABLE <TableName> DROP COLUMN <ColumnName>;
删除列的自增属性
How to drop identity property of Column
参考文献
Lesson 1: Create and query database objects[……]

READ MORE

「列出SQL Server中某个库中所有的存储过程」

最好的方式是使用information_schema。只要你不在master库上,系统存储过程就不会返回。

SELECT
*
FROM
DATABASENAME.INFORMATION_SCHEMA.ROUTINES
WHERE
ROUTINE_TYPE = ‘PROCEDURE’

如果由于某种原因,在master数据库中有非系统存储过程,则可以使用查询(这将过滤掉大多数系统存储过程):

SELECT
*
FROM
MASTER.INFORMATION_SCHEMA.ROUTINES
WHERE
ROUTINE_TYPE = ‘PROCEDURE’
AND LEFT(
ROUTINE_NAME,
3
) NOT IN(
‘SP_’,
‘XP_’,
‘MS_’
)

参考文献
Query to list all stored procedures:https://stackoverflow.com/questions/219434/query-to-list-all-stored-procedures[……]

READ MORE

「Linux」- SQL Server,管理工具

解决方案
mssql-tools
FreeTDS
Visual Studio Code,SQL Server Extension
https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-develop-overview
参考文献
How to get started developing applications for SQL Server on Linux: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-develop-overview[……]

READ MORE

「Linux下,mssql-tools安装及使用」

从发行版的源中安装

###########################################################################################
# Ubuntu 16.04.3 LTS
###########################################################################################

curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add –
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | tee /etc/apt/sources.list.d/msprod.list

apt-get update
apt-get install msodbcsql mssql-tools

###########################################################################################
# 其他的Linux发行版安装
# 参考官方文档:https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup-tools
###########################################################################################

安装的可执行程序
sqlcmd
Linux下的SQL Server命令行客户端。 sqlcmd官方手册: https://docs.microsoft.com/en-us/sql/tools/sqlcmd-utility
bcp
大批量的导入导出工具。 bcp官方手册:https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-connect-and-query-sqlcmd
注意
官方只提供了几个发行版的二进制包,而且也是没有源码的。我在Kali Linux Rolling上安装成功了,但是运行失败了(多半使库的原因),总是产生下面这个错误:

Sqlcmd: Error: Microsoft ODBC Driver 13 for SQL Server : Can’t open lib ‘/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9[……]

READ MORE

「mongoDB」- 安装(CentOS、Debian)

问题描述
该笔记将记录:在 Linux 中,如何安装 mongoDB 数据库,以及常见文件的处理方法。
解决方案
该笔记多以服务端的安装为主,及其相关的问题处理方法。
如果希望单纯的安装 mongoDB 客户端:

yum provides ‘*bin/mongo’

yum install yum-utils
repoquery –list mongodb-org-shell

yum install -y mongodb-org-shell

MongoDB 4.2 on CentOS 7.4
Install MongoDB Community Edition How to use SOCKS proxy with yum?

#### 第一步、添加 YUM 仓库
cat <<EOF > /etc/yum.repos.d/mongodb-org-4.2.repo
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc
EOF

### 第二步、安装数据库
yum install -y mongodb-org

MongoDB 3.6.5 on CentOS 7.4

#### 第一步、添加 YUM 仓库
cat <<EOF > /etc/yum.repos.d/mongodb-org-3.6.repo
[mongodb-org-3.6]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/3.6/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc
EOF

### 第二步、安装数据库
yum install -y mongodb-org-3.6.5

MongoDB 4.2 on Debian 10
Install MongoDB Community Edition on Debian

# 导入公钥
apt-get install gnupg
wget -qO – https://www.mongodb.org/s[……]

READ MORE

「MongoDB」- 管理与维护

常用端口号
How To Change MongoDB Default And Connect With MongoDB

Default Port
Description

27017
The default port for mongod and mongos instances.

27018
The default port when running with –shardsvr runtime operation.

27019
The default port when running with –configsvr runtime operation.

28017
The default port for the web status page.

客户端工具
Robo 3T
https://www.robomongo.org/download[……]

READ MORE