2018年6月

Environment variable ORACLE_UNQNAME not defined错误问题解决

查看dbconsole状态的时候报错:

C:\WINDOWS\system32>emctl status dbconsole
Environment variable ORACLE_UNQNAME not defined. Please set ORACLE_UNQNAME to database unique name.

其实就是
oracle_unqname没有设置
Windows下执行:

set oracle_unqname=$ORACLE_SID
如
C:\WINDOWS\system32>set oracle_unqname=orcl
再次运行即可:
C:\WINDOWS\system32>emctl status dbconsole
Oracle Enterprise Manager 11g Database Control Release 11.2.0.1.0
Copyright (c) 1996, 2010 Oracle Corporation.  All rights reserved.
https://A00263.hongsin.cn:1158/em/console/aboutApplication
Oracle Enterprise Manager 11g is running.
------------------------------------------------------------------
Logs are generated in directory E:\app\mahl01\product\11.2.0\dbhome_1/A00263.hongsin.cn_orcl/sysman/log

如果是Linux下需要设置ORACLE_UNQNAME和ORACLE_HOSTNAME:

export ORACLE_UNQNAME=$ORACLE_SID
export ORACLE_HOSTNAME=localhost

TNS-01190: 用户无权执行所请求的监听程序命令

执行了一个查看监听状态的命令:

C:\Users\mahl01>lsnrctl status
出现了下面的错误提示:
---------------------------------------------------------------------------------

LSNRCTL for 32-bit Windows: Version 11.2.0.1.0 - Production on 21-11月-2010 10:4

7:41

Copyright (c) 1991, 2010, Oracle.  All rights reserved.

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))

TNS-01190: 用户无权执行所请求的监听程序命令

先确认环境变量path是否设置
path.png

在命令提示符,以鼠标右键单击,选择“以管理员身份运行”,此时出现一个用户帐户控制页面,选择“是”,出现了LSNRCTL提示符
然后再运行即可:

C:\WINDOWS\system32>lsnrctl status

LSNRCTL for 64-bit Windows: Version 11.2.0.1.0 - Production on 27-6月 -2018 14:24:33

Copyright (c) 1991, 2010, Oracle.  All rights reserved.

正在连接到 (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))
LISTENER 的 STATUS
------------------------
别名                      LISTENER
版本                      TNSLSNR for 64-bit Windows: Version 11.2.0.1.0 - Production
启动日期                  27-6月 -2018 13:50:49
正常运行时间              0 天 0 小时 33 分 47 秒
跟踪级别                  off
安全性                    ON: Local OS Authentication
SNMP                      OFF
监听程序参数文件          E:\app\mahl01\product\11.2.0\dbhome_1\network\admin\listener.ora
监听程序日志文件          e:\app\mahl01\diag\tnslsnr\A00263\listener\alert\log.xml
监听端点概要...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1521ipc)))
  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=A00263.hongsin.cn)(PORT=1521)))
服务摘要..
服务 "CLRExtProc" 包含 1 个实例。
  实例 "CLRExtProc", 状态 UNKNOWN, 包含此服务的 1 个处理程序...
服务 "orcl" 包含 1 个实例。
  实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
服务 "orclXDB" 包含 1 个实例。
  实例 "orcl", 状态 READY, 包含此服务的 1 个处理程序...
命令执行成功

架构和运维技术高峰论坛参会有感

几个关键字:AIops机器人微服务容器

机器人这个概念几年前在巨人的时候,团队就已经提出来了,用robot代替人工巡检,定时批量去完成一些定义好的job,携程的专家说的好,招不下人的时候自己招个"机器人"来完成一些简单的任务,这也是个不错的idea。

微服务最近这两年很热,大小厂及团队都在搞,每个人对微服务的这个理解不太一样,但是基本都是这个模式,按功能模块切分,但要有个度,不能太细,对外提供统一API接口提供服务,语言可以是好几种组合,可以参考下面几个图;
1.jpg


---阅读剩余部分---

PostgreSQL备份与恢复

postgresql数据库的备份和还原命令pg_dump
单个库纯文本SQL格式的备份:

pg_dump -U postgres -d myDBname -f dump.sql

还原:

psql -U username -f filename dbname 

使用pg_dumpall备份:

pg_dumpall -U postgres > alldbs.pgsql

恢复所有数据库:

psql -f filename

备份和恢复单个表
备份:从一个名为mydb的数据库中备份mytable一个表。

pg_dump -U postgres -d mydb -t mytable > mydb-mytable.pgsql

还原:单表备份到数据库中还原。请确保您的备份文件包含要恢复唯一的单表备份。

psql -U postgres -d mydb 
pg_dump 把一个数据库转储为纯文本文件或者是其它格式.

用法:
  pg_dump [选项]... [数据库名字]

一般选项:
  -f, --file=FILENAME          输出文件或目录名
  -F, --format=c|d|t|p         输出文件格式 (定制, 目录, tar)
                               明文 (默认值))
  -j, --jobs=NUM               执行多个并行任务进行备份转储工作
  -v, --verbose                详细模式
  -V, --version                输出版本信息,然后退出
  -Z, --compress=0-9           被压缩格式的压缩级别
  --lock-wait-timeout=TIMEOUT  在等待表锁超时后操作失败
  -?, --help                   显示此帮助, 然后退出

控制输出内容选项:
  -a, --data-only              只转储数据,不包括模式
  -b, --blobs                  在转储中包括大对象
  -c, --clean                  在重新创建之前,先清除(删除)数据库对象
  -C, --create                 在转储中包括命令,以便创建数据库
  -E, --encoding=ENCODING      转储以ENCODING形式编码的数据
  -n, --schema=SCHEMA          只转储指定名称的模式
  -N, --exclude-schema=SCHEMA  不转储已命名的模式
  -o, --oids                   在转储中包括 OID
  -O, --no-owner               在明文格式中, 忽略恢复对象所属者

  -s, --schema-only            只转储模式, 不包括数据
  -S, --superuser=NAME         在明文格式中使用指定的超级用户名
  -t, --table=TABLE            只转储指定名称的表
  -T, --exclude-table=TABLE    不转储指定名称的表
  -x, --no-privileges          不要转储权限 (grant/revoke)
  --binary-upgrade             只能由升级工具使用
  --column-inserts             以带有列名的INSERT命令形式转储数据
  --disable-dollar-quoting     取消美元 (符号) 引号, 使用 SQL 标准引号
  --disable-triggers           在只恢复数据的过程中禁用触发器
  --enable-row-security        启用行安全性(只转储用户能够访问的内容)
  --exclude-table-data=TABLE   不转储指定名称的表中的数据
  --if-exists              当删除对象时使用IF EXISTS
  --inserts                    以INSERT命令,而不是COPY命令的形式转储数据
  --no-security-labels         不转储安全标签的分配
  --no-synchronized-snapshots  在并行工作集中不使用同步快照
  --no-tablespaces             不转储表空间分配信息
  --no-unlogged-table-data     不转储没有日志的表数据
  --quote-all-identifiers      所有标识符加引号,即使不是关键字
  --section=SECTION            备份命名的节 (数据前, 数据, 及 数据后)
  --serializable-deferrable   等到备份可以无异常运行
  --snapshot=SNAPSHOT          为转储使用给定的快照
  --strict-names               要求每个表和/或schema包括模式以匹配至少一个实体
  --use-set-session-authorization
                               使用 SESSION AUTHORIZATION 命令代替
  ALTER OWNER 命令来设置所有权

联接选项:
  -d, --dbname=DBNAME       对数据库 DBNAME备份
  -h, --host=主机名        数据库服务器的主机名或套接字目录
  -p, --port=端口号        数据库服务器的端口号
  -U, --username=名字      以指定的数据库用户联接
  -w, --no-password        永远不提示输入口令
  -W, --password           强制口令提示 (自动)
  --role=ROLENAME          在转储前运行SET ROLE

如果没有提供数据库名字, 那么使用 PGDATABASE 环境变量的数值.

PostgreSQL常用操作命令整理

使用yum安装PostgreSQL:
安装PostgreSQL客户端

yum install postgresql-client -y

安装PostgreSQL服务端:

yum install postgresql -y

安装完成后,PostgreSQL服务器会自动在本机的5432端口开启。
安装图形管理界面(可选)

yum install pgadmin3 -y

启动服务

service postgresql start

安装参考:https://www.unixso.com/PostgreSQL/centos7-4-install-postgresql10-1.html
进入控制台

psql -U dbuser -d exampledb -h 127.0.0.1 -p 5432

退出

postgres=# \q

创建用户

CREATE USER youusername WITH PASSWORD 'youpassword';

创建数据库并赋予用户

postgres=# CREATE DATABASE youdbname OWNER youusername;
postgres=# GRANT ALL PRIVILEGES ON DATABASE youdbname to youusername;
postgres=# \c youdbname;
postgres=# ALTER SCHEMA public OWNER to dbuser;
postgres=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO youusername;
postgres=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO youusername;

查看所有用户

postgres=# \du

更改密码

postgres=# \password youusername

删除用户

postgres=# drop user youusername ;

查看所有库

postgres=# \l

切换数据库

postgres=# \c exampledb

常用控制台命令

\password           设置密码。
\q                  退出。
\h                  查看SQL命令的解释,比如\h select。
\?                  查看psql命令列表。
\l                  列出所有数据库。
\c [database_name]  连接其他数据库。
\d                  列出当前数据库的所有表格。
\d [table_name]     列出某一张表格的结构。
\du                 列出所有用户。
\e                  打开文本编辑器。
\conninfo           列出当前数据库和连接的信息。

基本的 SQL 语句

# 创建新表
CREATE TABLE user_tbl(name VARCHAR(20), signup_date DATE);

# 插入数据
INSERT INTO user_tbl(name, signup_date) VALUES('张三', '2013-12-22');

# 查询记录
SELECT * FROM user_tbl;

# 更新数据
UPDATE user_tbl set name = '李四' WHERE name = '张三';

# 删除记录
DELETE FROM user_tbl WHERE name = '李四' ;

# 添加字段
ALTER TABLE user_tbl ADD email VARCHAR(40);

# 更改字段类型
ALTER TABLE user_tbl ALTER COLUMN signup_date SET NOT NULL;

# 设置字段默认值(注意字符串使用单引号)
ALTER TABLE user_tbl ALTER COLUMN email SET DEFAULT 'example@example.com';

# 去除字段默认值
ALTER TABLE user_tbl ALTER email DROP DEFAULT;

# 重命名字段
ALTER TABLE user_tbl RENAME COLUMN signup_date TO signup;

# 删除字段
ALTER TABLE user_tbl DROP COLUMN email;

# 表重命名
ALTER TABLE user_tbl RENAME TO backup_tbl;

# 删除表
DROP TABLE IF EXISTS backup_tbl;

# 删除库
\c hello2;
DROP DATABASE IF EXISTS hello;

MySQL报错This function has none of DETERMINISTIC解决

创建存储过程出错log

ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

原因:开启了bin-log就须指函数是否是

1 DETERMINISTIC 不确定的

2 NO SQL 没有SQl语句,当然也不会修改数据

3 READS SQL DATA 只是读取数据,当然也不会修改数据

4 MODIFIES SQL DATA 要修改数据

5 CONTAINS SQL 包含了SQL语句

其中在function里面,只有 DETERMINISTIC, NO SQL 和 READS SQL DATA 被支持。
如果开启了 bin-log, 我们就必须为function指定一个参数。
临时设置:

mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name          | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | OFF  |
+---------------------------------+-------+
mysql> set global log_bin_trust_function_creators=1;
mysql> show variables like 'log_bin_trust_function_creators';
+---------------------------------+-------+
| Variable_name          | Value |
+---------------------------------+-------+
| log_bin_trust_function_creators | ON  |

修改配置文件my.cnf在mysqld部分增加

log_bin_trust_function_creators=1
/etc/init.d/mysql restart

重启MySQL服务。

吃芒果过敏了

以前买芒果都是大点的,吃了好多次,也没过敏过;

这次买的小芒果,具体名字忘记了,结果吃了4个以后第二天过敏了,反应出来了,手背、胳膊上和腿上出来了好多小红片,有点痒,手“胖”了不少,冏、冏、冏......

---阅读剩余部分---

kafka报错INFO Reconnect due to socket error: java.nio.channels.ClosedChannelException (kafka.consumer.SimpleConsumer

kafka安装启动以后server.log一直报INFO Reconnect due to socket error: java.nio.channels.ClosedChannelException (kafka.consumer.SimpleConsumer错误信息,如下

[2018-06-19 09:43:29,783] INFO Reconnect due to socket error: java.nio.channels.ClosedChannelException (kafka.consumer.SimpleConsumer)
[2018-06-19 09:43:29,783] WARN [ReplicaFetcherThread-0-1], Error in fetch Name: FetchRequest; Version: 0; CorrelationId: 518500; ClientId: ReplicaFetcherThread-0-1; ReplicaId: 2; MaxWait: 500 ms; MinBytes: 1 bytes; RequestInfo: [a6,5] -> PartitionFetchInfo(0,1048576),[a6,3] -> PartitionFetchInfo(0,1048576),[a6,7] -> PartitionFetchInfo(0,1048576),[a6,1] -> PartitionFetchInfo(0,1048576),[a6,9] -> PartitionFetchInfo(0,1048576). Possible cause: java.nio.channels.ClosedChannelException (kafka.server.ReplicaFetcherThread)
[2018-06-19 09:43:29,783] INFO Reconnect due to socket error: java.nio.channels.ClosedChannelException (kafka.consumer.SimpleConsumer)
[2018-06-19 09:43:29,783] WARN [ReplicaFetcherThread-0-1], Error in fetch Name: FetchRequest; Version: 0; CorrelationId: 518501; ClientId: ReplicaFetcherThread-0-1; ReplicaId: 2; MaxWait: 500 ms; MinBytes: 1 bytes; RequestInfo: [a6,5] -> PartitionFetchInfo(0,1048576),[a6,3] -> PartitionFetchInfo(0,1048576),[a6,7] -> PartitionFetchInfo(0,1048576),[a6,1] -> PartitionFetchInfo(0,1048576),[a6,9] -> PartitionFetchInfo(0,1048576). Possible cause: java.nio.channels.ClosedChannelException (kafka.server.ReplicaFetcherThread)
[2018-06-19 09:43:29,783] INFO Reconnect due to socket error: java.nio.channels.ClosedChannelException (kafka.consumer.SimpleConsumer)
[2018-06-19 09:43:29,783] WARN [ReplicaFetcherThread-0-1], Error in fetch Name: FetchRequest; Version: 0; CorrelationId: 518502; ClientId: ReplicaFetcherThread-0-1; ReplicaId: 2; MaxWait: 500 ms; MinBytes: 1 bytes; RequestInfo: [a6,5] -> PartitionFetchInfo(0,1048576),[a6,3] -> PartitionFetchInfo(0,1048576),[a6,7] -> PartitionFetchInfo(0,1048576),[a6,1] -> PartitionFetchInfo(0,1048576),[a6,9] -> PartitionFetchInfo(0,1048576). Possible cause: java.nio.channels.ClosedChannelException (kafka.server.ReplicaFetcherThread)

原因是/etc/hosts文件里面没有添加kafka集群的机器名,

10.0.28.51 huafadb1
10.0.28.52 huafadb2

10.0.28.51    k1
10.0.28.52    k2
10.0.28.51    k3
                
10.0.28.51    z1
10.0.28.52    z2
10.0.28.51    z3

一般容易忘记前面两个主机名,huafadb1和huafadb2对应的IP,每个集群机器都添加,添加完成以后重启kafka服务即可解决。

Redis高可用方案之sentinel(哨兵集群)

Redis哨兵为Redis提供了高可用性。实际上这意味着你可以使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis部署。

监控:哨兵不断的检查master和slave是否正常的运行。
通知:当监控的某台Redis实例发生问题时,可以通过API通知系统管理员和其他的应用程序。
自动故障转移:如果一个master不正常运行了,哨兵可以启动一个故障转移进程,将一个slave升级成为master,其他的slave被重新配置使用新的master,并且应用程序使用Redis服务端通知的新地址。
配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址。

Redis哨兵是一个分布式系统:
哨兵自身被设计成和多个哨兵进程一起合作运行。有多个哨兵进程合作的好处有:

当多个哨兵对一个master不再可用达成一致时执行故障检测。这会降低错误判断的概率。
即使在不是所有的哨兵都工作时哨兵也会工作,使系统健壮的抵抗故障。毕竟在故障系统里单点故障没有什么意义。
Redis的哨兵、Redis实例(master和slave)、和客户端是一个有特种功能的大型分布式系统。

部署哨兵之前需要了解的基本事情:

一个健壮的部署至少需要三个哨兵实例。
三个哨兵实例应该放置在客户使用独立方式确认故障的计算机或虚拟机中。例如不同的物理机或不同可用区域的虚拟机。
sentinel + Redis实例不保证在故障期间保留确认的写入,因为Redis使用异步复制。然而有方式部署哨兵使丢失数据限制在特定时刻,虽然有更安全的方式部署它。
你的客户端要支持哨兵,流行的客户端都支持哨兵,但不是全部。
没有HA设置是安全的,如果你不经常的在开发环境测试,在生产环境他们会更好。你可能会有一个明显的错误配置只是当太晚的时候。
Sentinel,Docker,或者其他形式的网络地址交换或端口映射需要加倍小心:Docker执行端口重新映射,破坏Sentinel自动发现其他的哨兵进程和master的slave列表。

机器信息:
192.168.121.40 Master
192.168.121.41 Slave1
192.168.121.42 Slave2
Master(192.168.121.40)机器配置如下:
redis.conf

cat redis.conf | grep -v "#"

bind 127.0.0.1 192.168.121.40

protected-mode yes

port 6879

tcp-backlog 511

timeout 0

tcp-keepalive 300

daemonize yes

supervised no

pidfile "/usr/local/redis-4.0.10_6879/redis_6879.pid"

loglevel notice

logfile "/usr/local/redis-4.0.10_6879/redis_6879.log"

databases 16

always-show-logo yes
save 900 1
save 300 10
save 60 10000

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename "dump.rdb"

dir "/usr/local/redis-4.0.10_6879"

slave-serve-stale-data yes

slave-read-only yes

repl-diskless-sync no

repl-diskless-sync-delay 5

repl-disable-tcp-nodelay no

slave-priority 100

lazyfree-lazy-eviction no

lazyfree-lazy-expire no

lazyfree-lazy-server-del no

slave-lazy-flush no

appendonly yes

appendfilename "appendonly.aof"

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

aof-load-truncated yes

aof-use-rdb-preamble no

lua-time-limit 5000

cluster-node-timeout 15000

slowlog-log-slower-than 10000

slowlog-max-len 128

latency-monitor-threshold 0

notify-keyspace-events ""

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-size -2

list-compress-depth 0

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

hll-sparse-max-bytes 3000

activerehashing yes

client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes

slaveof 192.168.121.41 6879

Slave1和Slave2配置相同,只是bind处需要把IP改成41和42
Master的sentinel.conf哨兵配置文件:
Redis源码发布包包含一个sentinel.conf的文件,Master(192.168.121.40)机器配置如下:

cat sentinel.conf 
port 26879  
#1表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换,单sentinel节点无效(自己测试发现的)  
#如果3s内mymaster无响应,则认为mymaster宕机了  
#如果10秒后,mysater仍没活过来,则启动failover  
sentinel monitor mymaster 192.168.121.40 6879 1  
sentinel down-after-milliseconds mymaster 3000  
sentinel failover-timeout mymaster 10000  
daemonize yes  
#指定工作目录  
dir "/data/redis/sentinel-work"  
protected-mode no  
logfile "/data/redis/sentinellog/sentinel.log"  
# Generated by CONFIG REWRITE

Slave(192.168.121.41-42)机器配置同上
注意:以上配置中不存在的文件路径需要手动创建。哨兵可配置多个,最好是最少3个节点,配置相同。

启动集群
启动192.168.121.40-41--42各机器Redis节点命令如下:

/usr/local/redis-4.0.10_6879/src/redis-server /usr/local/redis-4.0.10_6879/redis.conf 

启动各Redis哨兵节点命令如下:

/usr/local/redis-4.0.10_6879/src/redis-sentinel /usr/local/redis-4.0.10_6879/sentinel.conf 

三台都启动完成以后登陆 列出Slave的信息

[root@wgq_idc_cache_3_40 redis-4.0.10_6879]# /usr/local/redis-4.0.10_6879/src/redis-cli -p 6879
127.0.0.1:6879> info Replication
# Replication
role:slave
master_host:192.168.121.41
master_port:6879
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:2049886
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:50eb71744c1aacc84bd865ff3af7ee1902395634
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:2049886
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1001311
repl_backlog_histlen:1048576

查看启动sentinel.log

cat sentinel.log 
4453:X 15 Jun 17:09:41.774 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4453:X 15 Jun 17:09:41.774 # Redis version=4.0.10, bits=64, commit=00000000, modified=0, pid=4453, just started
4453:X 15 Jun 17:09:41.774 # Configuration loaded
4454:X 15 Jun 17:09:41.779 * Running mode=sentinel, port=26879.
4454:X 15 Jun 17:09:41.779 # Sentinel ID is 5092d7a7096ec024a1d15e0fc903f7c289d4bd8a
4454:X 15 Jun 17:09:41.779 # +monitor master mymaster 192.168.121.40 6879 quorum 1
4454:X 15 Jun 17:12:47.369 # +sdown master mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.369 # +odown master mymaster 192.168.121.40 6879 #quorum 1/1
4454:X 15 Jun 17:12:47.369 # +new-epoch 1
4454:X 15 Jun 17:12:47.369 # +try-failover master mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.370 # +vote-for-leader 5092d7a7096ec024a1d15e0fc903f7c289d4bd8a 1
4454:X 15 Jun 17:12:47.371 # +elected-leader master mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.371 # +failover-state-select-slave master mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.442 # +selected-slave slave 192.168.121.42:6879 192.168.121.42 6879 @ mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.442 * +failover-state-send-slaveof-noone slave 192.168.121.42:6879 192.168.121.42 6879 @ mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:47.572 * +failover-state-wait-promotion slave 192.168.121.42:6879 192.168.121.42 6879 @ mymaster 192.168.121.40 6879
4454:X 15 Jun 17:12:48.401 # +promoted-slave slave 192.168.121.42:6879 192.168.121.42 6879 @ mymaster 192.168.121.40 6879

到这里我们已经完成了sentinel集群的搭建;
如果启动有此警告信息:

WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

方法1: 临时设置生效:

sysctl -w net.core.somaxconn = 65535
sysctl -w vm.overcommit_memory = 1

方法2: 永久生效: 修改/etc/sysctl.conf文件,增加一行

net.core.somaxconn = 65535
vm.overcommit_memory = 1

然后执行命令

sysctl -p

参考:http://redis.majunwei.com/topics/sentinel.html

ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务

Ucloud云上Oracle数据库服务器,由于物理机宕机重启,造成虚机也重启了,手动启动oracle服务和listen监听以后,PL/SQL客户端和应用都无法连接,提示“ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务”,数据库版本Oracle 11g R2,
初步判断是listener.ora 文件有问题,

# Generated by Oracle configuration tools.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 172.28.109.115)(PORT = 1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /data/app/oracle/product/11.2.0/db_1)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = earth_m1)
      (ORACLE_HOME = /data/app/oracle/product/11.2.0/db_1)
    )
  )

ADR_BASE_LISTENER = /data/app/oracle

备份原来监听文件:

cp /data/app/oracle/product/11.2.0/db_1/network/admin/listener.ora /tmp/listener.ora

修改为如下:

vim /data/app/oracle/product/11.2.0/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 172.28.109.115)(PORT = 1521))
    )
  )

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = powerdes)
      (ORACLE_HOME = /data/app/oracle/product/11.2.0/db_1)
      (SID_NAME = powerdes)
    )
    (SID_DESC =
      (SID_NAME = earth_m1)
      (ORACLE_HOME = /data/app/oracle/product/11.2.0/db_1)
    )
  )

ADR_BASE_LISTENER = /data/app/oracle

Listener主动加载服务

  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = powerdes)
      (ORACLE_HOME = /data/app/oracle/product/11.2.0/db_1)
      (SID_NAME = powerdes)
    )

添加GLOBAL_DBNAME后在使用lsnrctl start监听程序时会将listener的服务注册到进程监视器(pmon)中,如果没有这个配置,则为Listener被动加载服务由实例的pmon进程在listener中注册服务,对listener来讲,就是被动了,也就是为什么先启动监听后启动数据库能够正常连接的,反之不行的原因了。

Kvm虚拟机静态迁移

什么是静态迁移?
静态迁移:也叫做常规迁移、离线迁移(Offline Migration)。就是在虚拟机关机或暂停的情况下从一台物理机迁移到另一台物理机。因为虚拟机的文件系统建立在虚拟机镜像上面,所以在虚拟机关机的 情况下,只需要简单的迁移虚拟机镜像和相应的配置文件到另外一台物理主机上;如果需要保存虚拟机迁移之前的状态,在迁移之前将虚拟机暂停,然后拷贝状态至目的主机,最后在目的主机重建虚拟机状态,恢复执行。这种方式的迁移过程需要显式的停止虚拟机的运行。从用户角度看,有明确的一段停机时间,虚拟机上的服务不可用。这种迁移方式简单易行,适用于对服务可用性要求不严格的场合。

说明
(1)虚拟主机各自使用本地存储存放虚拟机磁盘文件
本文实现基于本地磁盘存储虚拟机磁盘文件的迁移方式

(2)虚拟主机之间使用共享存储存放虚拟机磁盘文件
该方式只是在目标虚拟主机上重新定义虚拟机就可以了

静态迁移过程
1、确定虚拟机关闭状态

[root@dev_test_25 ~]# virsh list --all
 Id    名称                         状态
----------------------------------------------------
 -     c160                           关闭
 -     wangya_win7                    关闭
 -     winxp_test                     关闭

2、准备迁移c160虚拟机,查看该虚拟机配置的磁盘文件

[root@dev_test_25 ~]# virsh domblklist c160
Target     Source
------------------------------------------------
vda        /home/c160
hdc        -

3、导出虚拟机配置文件

virsh dumpxml c160 > /opt/c160.xml

4、拷贝配置文件到目标主机上

scp /opt/c160.xml 192.168.121.200:/etc/libvirt/qemu/

5、拷贝虚拟磁盘文件

scp -r /home/c160 192.168.121.200:/kvm

目标虚拟主机
上面已经将虚拟机磁盘文件与配置文件都已经复制到目标虚拟主机上了。下面开始配置与启动。
1、对虚拟主机进行注册

virsh define /etc/libvirt/qemu/c160.xml

2、查看目标虚拟主机环境

virsh list --all
 Id    Name                           State
----------------------------------------------------
 8     c160                           shut off

3、确认源地址和迁移后的磁盘路径一致,如果不一致做个软连接即可,否则不能启动
如原来的路径在/home/c160,迁移以后的地址在/kvm/c160 做下软连接即可:

ln -s /kvm/c160 /home/c160

4、最后启动虚拟机

virsh start c160

启动完成以后可以ssh登陆上去检查下,至此kvm静态迁移完毕。
若把虚拟机静态迁移到不同平台(不同型号的cpu)的主机上,启动的时候报错,根据错误提示修改/etc/libvirt/qemu/下面的虚拟配置文件即可。

Keepalived构建高可用MySQL互为主从自动切换

关于MySQL-HA,目前有多种解决方案,比如heartbeat、drbd、mmm、共享存储,但是它们各有优缺点。heartbeat、drbd配置较为复杂,需要自己写脚本才能实现MySQL自动切换,对于不会脚本语言的人来说,这无疑是一种脑裂问题;对于mmm,生产环境中很少有人用,且mmm管理端需要单独运行一台服务器上,要是想实现高可用,就得对mmm管理端做HA,这样增加了硬件开支;对于共享存储,数据还是放在本地较为安全,存储设备毕竟存在单点隐患。

Keepalived是一个免费开源的,用C编写的类似于layer3, 4 & 7交换机制软件,具备我们平时说的第3层、第4层和第7层交换机的功能。主要提供loadbalancing(负载均衡)和 high-availability(高可用)功能,负载均衡实现需要依赖Linux的虚拟服务内核模块(ipvs),而高可用是通过VRRP协议实现多台机器之间的故障转移服务。
keepalived.jpg
上图是Keepalived的功能体系结构,大致分两层:用户空间(user space)和内核空间(kernel space)。
内核空间:主要包括IPVS(IP虚拟服务器,用于实现网络服务的负载均衡)和NETLINK(提供高级路由及其他相关的网络功能)两个部份。
用户空间:

WatchDog:负载监控checkers和VRRP进程的状况
VRRP Stack:负载负载均衡器之间的失败切换FailOver,如果只用一个负载均稀器,则VRRP不是必须的。
Checkers:负责真实服务器的健康检查healthchecking,是keepalived最主要的功能。换言之,可以没有VRRP Stack,但健康检查healthchecking是一定要有的。
IPVS wrapper:用户发送设定的规则到内核ipvs代码
Netlink Reflector:用来设定vrrp的vip地址等。

使用MySQL双master+keepalived是一种非常好的解决方案,在MySQL-HA环境 中,MySQL互为主从关系,这样就保证了两台MySQL数据的一致性,然后用keepalived实现虚拟IP,通过keepalived自带的服务监控功能来实现MySQL故障时自动切换。

实现过程如下:
1、机器网络拓扑等信息:

MySQL-VIP:10.10.200.30    
mysqldb1:10.10.200.11    
mysqldb2:10.10.200.12   
   
OS版本:CentOS 7.4    
MySQL版本:5.7.22    
Keepalived版本:1.4.5

2、MySQL配置文件修改:
db1和db2互为主从,需要修改server-id为不同,具体参考基于GTID的主从复制过程实现:https://www.unixso.com/MySQL/gtid-master-slave.html
如上述均正确配置,现在任何一台MySQL上更新数据都会同步到另一台MySQL,即互为主从,MySQL同步在此叙述。
3、keepalived安装及配置

yum install popt popt-devel libnl libnl-devel libnfnetlink-devel -y #安装基础库文件
wget http://www.keepalived.org/software/keepalived-1.4.5.tar.gz
tar xvf keepalived-1.4.5.tar.gz
cd keepalived-1.4.5.tar.gz
./configure --prefix=/usr/local/keepalived --sbindir=/usr/local/keepalived/sbin
make && make install
ln -s /usr/local/sbin/keepalived /usr/sbin/  
ln -s /usr/local/keepalived/etc/keepalived/ /etc/keepalived
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/init.d/  
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
chmod +x /etc/init.d/keepalived  
chkconfig keepalived on   #CentOS6执行
systemctl enable keepalived

配置keepalived
默认情况下keepalived启动时会去/etc/keepalived目录下找配置文件

#vi /etc/keepalived/keepalived.conf  
global_defs {  
     notification_email {  
         xxx@xxx.com
     }  
     notification_email_from xxx@xxx.com  
     smtp_server x.x.x.x
     smtp_connect_timeout 30  
     router_id MySQL-ha  
}  
 
vrrp_instance VI_1 {  
     state BACKUP   #两台配置此处均是BACKUP  
     interface eth0  
     virtual_router_id 51  
     priority 100   #优先级,另一台改为90  
     advert_int 1  
     nopreempt  #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置  
     authentication {  
         auth_type PASS  
         auth_pass 1111  
     }  
     virtual_ipaddress {  
         10.10.200.30  
     }  
}  
 
virtual_server 10.10.200.30 3306 {  
     delay_loop 2   #每个2秒检查一次real_server状态  
     lb_algo wrr   #LVS算法  
     lb_kind DR    #LVS模式  
     persistence_timeout 60   #会话保持时间  
     protocol TCP  
     real_server 10.10.200.11 3306 {  
         weight 3  
         notify_down /usr/local/mysql/bin/mysql.sh  #检测到服务down后执行的脚本  
         TCP_CHECK {  
             connect_timeout 10    #连接超时时间  
             nb_get_retry 3       #重连次数  
             delay_before_retry 3   #重连间隔时间  
             connect_port 3306   #健康检查端口
         }
     }  
} 

检测服务down后所要执行的脚本

#!/bin/sh    
killall keepalived    

赋予执行权限

chmod +x /usr/local/mysql/bin/mysql.sh  

此脚本是上面配置文件notify_down选项所用到的,keepalived使用notify_down选项来检查real_server 的服务状态,检测到real_server服务故障时,执行强制杀死keepalived进程,从而实现MySQL故障自动转移。
操作完成以后启动keepalived服务

systemctl keepalived start
或
/usr/local/keepalived/sbin/keepalived –D 

mysqldb2:10.10.200.12 机器上也依此安装keeplaived服务
配置keepalived文件,优先级为90、无抢占设置、real_server为本机IP这三个地方不同:

vi /etc/keepalived/keepalived.conf
global_defs {  
     notification_email {  
         xxx@xxx.com  
     }  
     notification_email_from xxx@xxx.com  
     smtp_server x.x.x.x  
     smtp_connect_timeout 30  
     router_id MySQL-ha  
}  
 
vrrp_instance VI_1 {  
     state BACKUP  
     interface eth0  
     virtual_router_id 51  
     priority 90  
     advert_int 1  
     authentication {  
         auth_type PASS  
         auth_pass 1111  
     }  
     virtual_ipaddress {  
         10.10.200.30
     }  
}  
 
virtual_server 10.10.200.30 3306 {  
     delay_loop 2  
     lb_algo wrr  
     lb_kind DR  
     persistence_timeout 60  
     protocol TCP  
     real_server 10.10.200.12 3306 {  
         weight 3  
         notify_down /usr/local/mysql/bin/mysql.sh  
         TCP_CHECK {  
             connect_timeout 10  
             nb_get_retry 3  
             delay_before_retry 3  
             connect_port 3306  
         }
     }
}

复制mysql.sh脚本、启动keepalived服务
测试
停止MySQL服务,看keepalived健康检查程序是否会触发我们编写的脚本,然后登录VIP,看是否能登录,在登录之两台MySQL服务器都要授权允许从远程登录,在切换时执行了一个MySQL查询命令,从执行show databases到显示出结果时间为2-3秒,会有

ERROR 2006 (HY000): MySQL server has gone away

报错信息,是因为keepalived切换大概为1-3秒左右,这3秒左右VIP是空白期,代码里面最好能实现多次重连数据库,从而规避,keepalived只能做到对3306的健康检查,但是做不到比如像 MySQL复制中的slave-SQL、slave-IO进程的检查,总之Keeplavied+Mysql互为主从是一个低廉的负载均衡解决方案。

Nginx中虚拟目录alias和root目录说明

Nginx的配置中,alias目录和root目录是有区别的:
1、alias指定的目录是准确的,即location匹配访问的path目录下的文件直接是在alias目录下查找的;
2、root指定的目录是location匹配访问的path目录的上一级目录,这个path目录一定要是真实存在root指定目录下的;
3、使用alias标签的目录块中不能使用rewrite的break(具体原因不明);另外,alias指定的目录后面必须要加上"/"符号!!
4、alias虚拟目录配置中,location匹配的path目录如果后面不带"/",那么访问的url地址中这个path目录后面加不加"/"不影响访问,访问时它会自动加上"/";
如果location匹配的path目录后面加上"/",那么访问的url地址中这个path目录必须要加上"/",访问时它不会自动加上"/"。如果不加上"/",访问就会失败!
5、root目录配置中,location匹配的path目录后面带不带"/",都不会影响访问。

nginx指定文件路径有两种方式root和alias,指令的使用方法和作用域:
[root]
语法:root path
默认值:root html
配置段:http、server、location、if
[alias]
语法:alias path
配置段:location

root与alias主要区别在于nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。
root的处理结果是:root路径+location路径
alias的处理结果是:使用alias路径替换location路径
alias是一个目录别名的定义,root则是最上层目录的定义。

还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root则可有可无。
所以,一般情况下,在nginx配置中的良好习惯是:
在location /中配置root目录;
在location /path中配置alias虚拟目录。
alias在使用正则匹配时,必须捕捉要匹配的内容并在指定的内容处使用。

最新

分类

归档

评论

  • Liang: 贴下编译参数和步骤,...
  • shao3911: 您好,为什么我在编译...
  • aliang: 先看是yum安装还是...
  • aliang: 将原来的nginx安...
  • yen: 3、如果要回滚的话,...
  • yen: 刚好需要升级ngin...
  • 文雨: 一些新的method...
  • aliang: 默认不屏蔽估计开发团...
  • 山野愚人居: PHP既然允许直接使...
  • aliang: 最下面有github地址·

其它