分类: DB

关于时序数据库influxdb的基本说明与使用整理

InfluxDB 是一种时序数据库,时序数据库通常被用在监控场景,比如运维和 IOT(物联网)领域。这类数据库旨在存储时序数据并实时处理它们。
可以写一个程序将服务器上 CPU 的使用情况每隔 10 秒钟向 InfluxDB 中写入一条数据。接着,我们写一个查询语句,查询过去 30 秒 CPU 的平均使用情况,然后让这个查询语句也每隔 10 秒钟执行一次。最终,我们配置一条报警规则,如果查询语句的执行结果>xxx,就立刻触发报警。
上述就是一个指标监控的场景,在 IOT 领域中,也有大量的指标需要我们监控。比如, 机械设备的轴承震动频率,农田的湿度温度等等。

为什么不用关系型数据库

  1. 写入性能
    关系型数据库也是支持时间戳的,也能够基于时间戳进行查询。但是,从我们的使用场景出发,需要注意数据库的写入性能。通常,关系型数据库会采用 B+树数据结构,在数据写入时,有可能会触发叶裂变,从而产生了对磁盘的随机读写,降低写入速度。
    数据价值

  2. 时间不可倒流,数据只写不改
    我们之前说,时序数据库一般用于指标监控场景。这个场景的数据有一个非常明显的特点就是冷热差别明显。通常,指标监控只会使用近期一段时间的数据,比如我只查询某个设备最近 10 分钟的记录,10 分钟前的数据我就不再用了。那么这 10 分钟前的数据,对我们来说就是冷数据,应该被压缩放到磁盘里去来节省空间。而热数据因为经常要用,数据库就应该让它留在内存里,等待查询。而市面上的时序数据库大都有类似的设计。

  3. 时间不可倒流,数据只写不改
    时序数据是描述一个实体在不同时间所处的不同状态。
    就像是我们打开任务管理器,查看 CPU 的使用情况。我发现 CPU 占用率太高了,于是杀死了一个进程,但 10 秒前的数据不会因为我关闭进程再发生改变了。这是时序数据的一大特点。与之相应,时序数据库基本上是插入操作较多,而且还没有什么更新需求。

一些概念

Bucket桶
是influxDb中基本存储单元 用于组织和存储时间序列数据 他是数据的逻辑容器,用于区分和隔离不同类型或来源的数据
oraganization 组织
用于隔离和管理用户 应用程序或者项目 每个用户可以属于一个或者多个组织 Bucket 也属于一个组织
Measurement 测量值
是influxDb中的数据表的概念 他类似关系型数据库中的数据表 用于存储时间序列数据 每个Measurement 包含一组字段和标签
Field 字段
field 是 Measurement 中的一种数据类型 用于存储实际的数值数据 例如温度 湿度 等是字段的例子
Tag标签
Tag 是 Measurement 中的一种索引类型 用于标识和过滤数据 标签通常用于存储维度信息 例如设备ID 地理位置 等是字段的例子
Point数据点
Point 是influxDb中时间序列数据的基本单位 它包含了时间戳 字段 标签 每个数据点都关联到一个Measurement
API密钥和访问令牌
为了进行安全的访问和操作
2.x 引入了Api 密钥和访问令牌 API密钥用于身份验证 而访问令牌用于授权对数据的访问
Flux查询语言
Flux是2.x 中的查询语言 用于执行强大的数据处理和分析操作 它支持灵活的 查询 过滤 聚合和转换操作
仪表盘和可视化
2.x 提供了仪表盘 和可视化工具 允许用户创建 定制 和共享图表 和仪表盘 以直观的展示时间序列数据

概念是oraganization,所有的数据都是属于org的。数据的存储都是在bucket里面。可以理解为数据库,2.x版本中没有database这个概念了。measurement可以理解成为一张表,但是实际上不是一个表。数据中point表示一条数据,每条数据都有一个_time表示时间戳,series表示point的集合,field是固定字段_field,key和value都是值,没有索引,tag是自定义字段名和值,索引的结合

Docker安装PostgreSQL

Docker安装PostgreSQL

拉取镜像

docker pull postgres:latest

用于生成默认的配置文件

docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf

启动容器

docker run -d \
-p 15432:5432 \
--restart=always \
--name docker-postgres \
--privileged=true \
-e TZ=Asia/Shanghai \
-e PGTZ=Asia/Shanghai \
-e POSTGRES_USER=iuu_postgres \
-e POSTGRES_PASSWORD=iuu_postgres \
-v /home/Software/Docker/postgres/postgres.conf:/etc/postgresql/postgresql.conf \
-v /home/Software/Docker/postgres/data:/var/lib/postgresql/data \
postgres:latest \
-c 'config_file=/etc/postgresql/postgresql.conf'

进入容器

docker exec -it docker-postgres  /bin/bash
# 直接进入pgsql
docker exec -it docker-postgres psql -U iuu_postgres

查看所有数据库

\list

查看所有数据库

SELECT datname FROM pg_database;

查看当前时区

show time zone; 或者 show timezone;

查看数据库的时区与时间:

SELECT now();

查看数据库可供选择的时区:

select * from pg_timezone_names;

设置时区:

set time zone "Asia/Shanghai";

但是通过这种方式设置时区在你退出psql终端后,再次进入此psql中断后就会发现又恢复到原来的时区了,如果想永久修改,我们需要更改配置文件:

log_timezone = 'PRC'
timezone = 'PRC'
# 'PRC' 改为 'Asia/Shanghai'

基于Docker 实现MySql的主从复制

1、新建主服务容器实例3310
================================
docker run -d -p 3310:3306 --name mysql-master \
-v /Users/iuu/Developer/docker/mysql/master/log:/var/log/mysql \
-v /Users/iuu/Developer/docker/mysql/master/data:/var/lib/mysql \
-v /Users/iuu/Developer/docker/mysql/master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
-e LANG="C.UTF-8" \
mysql:latest 
================================
2、新建my.cnf
================================
[mysqld]
# 设置server_id 同一局域网中要唯一
server_id=101

# 无需开启二进制日志文件的数据库
# 多个数据库则要重复设置
binlog-ignore-db=mysql

# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.
log-bin=mall-mysql-bin 

# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size=10M

# binlog日志格式
# mysql默认采用statement,建议使用mixed
binlog_format=mixed

# 超过指定天数的binlog将被删除
# 二进制日志过期时间设置为7天(7天 = 7 * 24 * 60 * 60 秒)
binlog_expire_logs_seconds = 604800

# 主从复制跳过错误
# 1062 指一些主键重复
# 1032 主从数据库数据不一致
# 跳过指定error no类型的错误
# slave-skip-errors=1062,1053,1146 
# 跳过所有错误
# slave-skip-errors=all 
slave-skip-errors=1062
================================
3、修改完配置后重启 master 实例
================================
docker restart mysql-master
================================
4、进入master容器
================================
docker exec -it mysql-master /bin/bash
mysql -uroot -p
show databeses;
================================
5、master 容器实例内创建数据同步用户
================================
创建用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
授权
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
================================
6、新建从服务器实例 3311
================================
docker run -d -p 3311:3306 --name mysql-slave \
-v /Users/iuu/Developer/docker/mysql/slave/log:/var/log/mysql \
-v /Users/iuu/Developer/docker/mysql/slave/data:/var/lib/mysql \
-v /Users/iuu/Developer/docker/mysql/slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
-e LANG="C.UTF-8" \
mysql:latest 
================================
7、新建my.cnf
================================
[mysqld]
# 设置server_id 同一局域网中要唯一
server_id=102

# 无需开启二进制日志文件的数据库
# 多个数据库则要重复设置
binlog-ignore-db=mysql

# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.
log-bin=mall-mysql-slave1-bin 

# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size=10M

# binlog日志格式
# mysql默认采用statement,建议使用mixed
binlog_format=mixed

# 超过指定天数的binlog将被删除
# 二进制日志过期时间设置为7天(7天 = 7 * 24 * 60 * 60 秒)
binlog_expire_logs_seconds = 604800

# 主从复制跳过错误
# 1062 指一些主键重复
# 1032 主从数据库数据不一致
# 跳过指定error no类型的错误
# slave-skip-errors=1062,1053,1146 
# 跳过所有错误
# slave-skip-errors=all 
slave-skip-errors=1062

# 配置中继日志
relay_log=mall-mysql-relay-bin

# 启用从库记录复制操作到自己的二进制日志
log_slave_updates = ON

# 限制一个 MySQL 实例的读写操作。
# 0 允许读写操作(默认行为)
# 当设置为 1 时,表示只允许读操作,而写操作会被拒绝
read_only=1
================================
8、修改完配置后重启 slave 实例
================================
docker restart mysql-slave
================================
9、在主数据库中查看主从同步状态
================================
show master status;
================================
10、进入 slave 服务器
================================
docker exec -it mysql-slave /bin/bash
mysql -uroot -p
show databeses;
================================
11、在从数据库中配置主从复制
================================
change master to 
master_host='192.168.1.8',
master_user='slave',
master_password='123456',
master_port=3310,
master_log_file='mall-mysql-bin.000002',
master_log_pos=712,
master_connect_retry=30;
================================
12、在从数据库中查看主从同步状态
================================
show slave status \G;
show slave status;
看这两个参数
Slave_IO_Running: No
Slave_SQL_Running: No
================================
13、在从数据库中开启主从同步
================================
start slave;
================================
14、查看从数据库状态发现已经同步
================================
show slave status \G;
================================
15、主从复制测试
================================
主机新建库
create database db01;
主机新建表
use db01;
create table t1 (id int, name varchar(20));
主机插入数据
insert into t1 values(1,'张三');
主机查看数据
select * form t1;
从机查看数据
select * form t1;
================================

MySQL数据误删恢复

DELETE FROM `users` WHERE `id` NOT IN(1,2)

我意识到我闯祸了
19:40-21:55 谷歌百度不知道打开了多少网页 终于补救回来了
我这次是运气好服务器开启了日志
要不然哭都没地哭
数据库要定期备份
一定要开启日志!!!!

总结:

所谓数据库数据恢复可以理解为 让数据库在一段时间内执行的sql语句重新执行(注意是执行到删除之前一分钟)

当我意识到删除之后有点慌,因为数据表引擎是InnoDB 所以我多少的感觉到应该可以恢复(其实我心里一点底都没有,就是感觉),于是赶紧谷歌百度,爬了很多文档之后有一句话感觉很对就照做了

  • 不要在写入新数据了,会导致数据污染,更难恢复

之前有了解过误删文件恢复,大概意思就是当想找回误删的文件时千万不要在哪个磁盘中写入新文件,会导致文件覆盖

于是我:

  • 关闭网站
  • 备份当前存在的数据
  • 关闭定时任务(我的定时任务是往数据库写入数据的)

通过搜索得知binlog这个东西(其实就是日志)

想要恢复数据,首先想到的也是日志:有无所有SQL操作的记录日志,有无开启binlog同步日志。这样才能根据SQL记录重新恢复数据,否则,数据将无法找回。
其次,我们需要查以下MySQL服务器开启了哪些日志,于是首先查看MySQL的配置文件 /etc/my.cnf ,发现开启了errorlogslowlogbinlog,这时就可以松一口气了,因为只要有binlog,所有数据都将找得回来,slowlog对我们当前的问题来说并没有什么用,errorlog后面我们拿来查找问题原因也许会有用。

万幸我的mysql开启了binlog日志

show variables like 'log_%'; 


log_bin 是开启状态

查看当前有哪些binlog文件

show binary logs;


发现有3个binlog文件,我们再来查看当前正在使用的binlog文件是哪个

查看当前使用的binlog文件

show master status;


进入到MySQL的数据存放目录 /www/server/data/,先将这几个binlog文件备份起来,以便防止数据丢失。

进入日志目录中

 cd /www/server/data/

备份

# 在用户目录下创建文件夹
mkdir -p ~/mysql-bin-backup
# 拷贝当前目录下所有mysql-bin.开头的文件 到 mysql-bin-backup
cp mysql-bin.* ~/mysql-bin-backup/ -r

将日志转SQL

几个参数了解一下
--start-datetime="开始时间"
--stop-datetime="结束时间"
--database=数据库名称

这段命令的意思是 读取 mysql-bin.000004 开始时间 到 结束时间 指定数据库的操作 转成sql文件

/www/server/mysql/bin/mysqlbinlog  --start-datetime="2019-12-07 00:00:00" --stop-datetime="2019-12-13 19:40:00" --database=vip_elemecps_com  /root/mysql-bin-backup/mysql-bin.000004 > ~/66666.sql

恢复数据

我是在本地导入的
本地终端链接mysql

创建个数据库
进入数据库

导入sql文件

你会发现你的数据库又回来了哈哈哈哈哈

知识扩展:

mysql是否开启binlog日志:

终端运行:

show variables like 'log_bin';

如果Value 为 OFF 则为开启日志文件

开启方法:

找到my,cnf 中 [mysqld] 添加如下

[mysqld]
# binlog 配置
log-bin = /usr/local/var/mysql/logs/mysql-bin.log
expire-logs-days = 14
max-binlog-size = 500M
server-id = 1

如果没有my.cnf 或者是集成的环境 找到my.ini 中 [mysqld] 添加如下:

[mysqld]
# binlog 配置
log-bin = /usr/local/var/mysql/logs/mysql-bin.log
expire-logs-days = 14
max-binlog-size = 500M
server-id = 1

重启mysql后

show variables like 'log_bin'; 

value 为 ON 即可