在Linux中使用date命令修改系统时间不生效

当我们使用date命令来修改系统时间的时候,发现命令返回修改成功

date -s '2021-03-04 11:21:13'

通过上面的命令执行,可以看到返回修改成功后的系统时间

Thu Mar  4 11:21:13 CST 2021

当我们再次运行date命令来查看系统时间的时候发现时间还是修改之前的,原因是现代的linux操作系统都会默认运行NTP这个时间同步服务,如果需要手动修改系统时间,那么需要先关闭同步功能,通过命令 timedatectl可以看到系统的时间情况

root@nbear:/opt/c# timedatectl
      Local time: Thu 2021-03-04 09:45:24 CST
  Universal time: Thu 2021-03-04 01:45:24 UTC
        RTC time: Thu 2021-03-04 01:45:24
       Time zone: Asia/Shanghai (CST, +0800)
 Network time on: yes
NTP synchronized: no
 RTC in local TZ: no

可以看到默认 Network time  on 这个选项是 yes的,所以我们需要先通过下面的命令关闭这个同步特性。

timedatectl set-ntp false

      Local time: Thu 2021-03-04 09:57:05 CST
  Universal time: Thu 2021-03-04 01:57:05 UTC
        RTC time: Thu 2021-03-04 01:57:05
       Time zone: Asia/Shanghai (CST, +0800)
 Network time on: no
NTP synchronized: yes
 RTC in local TZ: no

这样你就可以自己修改时间了,如果要恢复只需要运行

timedatectl set-ntp true

发表在 Linux | 标签为 , | 留下评论

MySQl中redo log和binlog的区别

使用MySQL数据库的时候通常会听说有日志系统,最常听说的就是redolog和binlog,那么两种日志有什么不同呢。

首先,两个的层次不一样,学过MySQL的小伙伴都知道MySQL逻辑分层中有着 服务层(Server)和数据库引擎层,其中binlog就是服务层的功能,而redolog则是innodb这个数据库引擎自己的功能,逻辑结构如图所示:

image.png

 其次在存储方面,虽然两者都是采用写入磁盘的数据结构,但是两个的方式并不一样。其中redolog采用一个类似环形存储区的方式进行存储,也就是有大小限制(my.cnf 中 innodb_log_file_size 用来设定redolog大小),一旦写到尾部则从新覆盖头部继续写;binlog则采用rotate分片的形式记录日志,可以不断追加,如果不特意配置则没有大小限制。

The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions. 

Redolog有两个关键的位置点(position),其中write position就是从这个地方继续追加新的日志,而check point 则是将redo日志写回磁盘到达的位置,从write position到 checkpoint两者之间的空间就是剩余的可追加日志空间。如果write position已经追上了checkpoint,那就要求数据库引擎innodb赶紧将内容写回磁盘后才能记录写redolog。

image.png

再者存储格式和方法也不尽相同,binlog虽然叫做bin(以二进制形式存储),但是实际存储的是逻辑操作过程,也就是比如 insert into user id,username values(3,'root') 这种形式,而redolog更像是磁盘上发生的变化。

功能类似但不完全相同,binlog用于记录整个历史记录,而redolog虽然也能用于恢复,但是设计之初的主要目的是缓存未提交的修改,比如我们update user set gender='famele' where username like '%lucy'  ,可能需要扫描很多行并且有很多行需要修改,如果直接去修改磁盘可能有性能问题,不如先把要操作的记录写到redolog之中,然后就可以返回已经更新完成,然后在空闲时间慢慢写回磁盘即可。

redolog的工作路程

redolog的基本工作流程,先写入redolog,写入完成返回给客户端写入成功,然后redolog再写回到磁盘,因此再写完redolog系统崩溃或者mysql进程崩溃,数据是不会丢失是可以恢复的。

两阶段提交

更新数据写入redolog,这时候的这个日志是 prepare状态,然后执行器生成binlog日志,并把binlog写入磁盘完成后,执行器调用数据库存储引擎的事务提交接口,引擎现在从prepare状态改成commit状态,于是更新完成。

两阶段提交可以保证binlog和redolog的一致性,避免恢复的时候使用不同日志导致数据不一致的问题。

发表在 MySQL | 标签为 , , | 留下评论

GIT config GIT配置详解

GIT的配置体系和CSS类似,有着三级结构,分别是

系统级(system)用户级(global)当前项目级(local)

三个等级的配置文件越靠近当前项目则优先级越高,因此当前项目下的配置文件是最高的配置优先级

image.png

GIT Config工具的使用

高手们可以直接修改配置文件完成配置,但是GIT本身提供了配置命令行,可以使用git config 进行配置

git config
usage: git config [<options>]
Config file location
    --global              use global config file
    --system              use system config file
    --local               use repository config file
    -f, --file <file>     use given config file
    --blob <blob-id>      read config from given blob object
Action
    --get                 get value: name [value-regex]
    --get-all             get all values: key [value-regex]
    --get-regexp          get values for regexp: name-regex [value-regex]
    --get-urlmatch        get value specific for the URL: section[.var] URL
    --replace-all         replace all matching variables: name value [value_regex]
    --add                 add a new variable: name value
    --unset               remove a variable: name [value-regex]
    --unset-all           remove all matches: name [value-regex]
    --rename-section      rename section: old-name new-name
    --remove-section      remove a section: name
    -l, --list            list all
    -e, --edit            open an editor
    --get-color           find the color configured: slot [default]
    --get-colorbool       find the color setting: slot [stdout-is-tty]
Type
    --bool                value is "true" or "false"
    --int                 value is decimal number
    --bool-or-int         value is --bool or --int
    --path                value is a path (file or directory name)
    --expiry-date         value is an expiry date
Other
    -z, --null            terminate values with NUL byte
    --name-only           show variable names only
    --includes            respect include directives on lookup
    --show-origin         show origin of config (file, standard input, blob, command line)


GIT config的实战操作

列出GIT的配置项目

#这个命令会列出所有的配置项,包含 系统级/用户级/当前项目级
#不同级别下有相同的配置则分别都会列出来
git config --list

#只列出系统级的配置
git config --system --list
#只列出用户级的配置
git config --global --list 
#只列出当前项目级的配置
git config --local --list

获取精准的配置项目

#获取当前git提交时用的用户名
#不加--system 这些范围作用域的话,如果各个作用域都有相同配置,则以 当前项目级>用户级>系统级 顺序获取
git config --get user.name

#调用编辑器进行修改配置

git config --global --edit

image.png

发表在 GIT | 标签为 , | 留下评论

OpenWRT luci使用详解和实例

CBI 模块的具体使用

m = Map("ctw", translate("微信连WiFi"))
s = m:section(TypedSection, "wifi")
s.addremove = false --可以添加模块,如果true,每次点击添加都会添加完整的一个模块的内容让用户输入
s.anonymous = true

首先是把整个UCI文件 Map 一下,然后再通过 section 方法进行对应,匿名节点爱用 TypedSection 非匿名节点采用 NamedSection

m:section(TypedSection,"wifi","描述信息")
m:section(NamedSection,"wifi","system","描述信息")

然后就是各个模块的映射:

Value 是普通的输入框

TextValue 则是类是textarea的文本输入框体

DummyValue 则是直接显示不可输入的内容框

Flag 则是复选框的,如果是勾选则为1 true 这样的关键词,没有勾选则为 0 false 这样的关键词

ListValue 则是下拉式列表框,这个框体里面可以提供下拉列表值

MultiValue 则是复选框,多个都被选中的时候会出现 option appid "1 2 3" 这样的内容

StaticList 则是复选框,但是会采用 list 方式存储而不是option 方式存储

FileUpload 文件上传,至少能记录文件名称

FileSelect 文件选择,选择设备系统中的文件名称

appid = s:option(Value, "appid", translate("<font color='red'>应用ID(appid)</font>"),"每个微信公共号唯一的appid标示")
appid:value("智能预选择值内容")
appid:depends("mode","fit");  #depends(key,value)  只有当对应的key=value的时候才能显示这个选项
appsecret = s:option(TextValue, "appsecret", translate("应用Secret(appsecret)"),"非必填项目,填写后可以用于高级功能")

enable = s:option(Flag, "enable", translate("Enable))
enable.rmempty = false -- 值为空时不删除
o = s:option(ListValue, "enable", translate("Enable"))
o:value("1", translate("Enable"))
o:value("0", translate("Disable"))
o = s:option(MultiValue, "enable", translate("Enable"))
o:value("1", translate("1"))
o:value("2", translate("2"))

关于依赖值的设计,支持多个依赖

auth:depends({mode="sta", eap_type="peap", encryption="wpa2"})

显示密码形式

acct_secret.password = true
encr.override_values = true                                                                                          
encr.override_depends = true

非常有用的写法,可以方便快捷的通过开关设置字符串类型的值

encryption = s:option(Flag,"encryption",translate("是否启用加密"))    
encryption.default = encryption.enabled                                     
encryption.enabled = "wpa-psk2"                                             
encryption.disabled = "none"

button = modex:option(Button, "modename", "桥接模式")
button.inputtitle = translate("切换")
button.inputstyle = "apply"
function button.write(self, section, value)
    AbstractValue.write(self, section, value)
    luci.sys.call("uci set network.lan.ifname=\"eth0.1 eth0.2\" ;uci del network.wan")
    --self.inputtitle = translate("路由模式")
    return
end

——————————————————————————–

刷新按钮

hup = s2:option(Button, "_refresh", translate("Refresh"))                              
hup.inputstyle = "reload"                                                              
function hup.write(self, section)                                                      
        luci.http.redirect(luci.dispatcher.build_url("admin/network/network",""))      
end

——————————————————————————–

实现表单的效果

f = SimpleForm("sac_list", translate("AP列表"), translate("当设备工作在AC模式时显示AP状态列表"))
f.reset = false
f.submit = false

t = f:section(Table, {{client_ip="192.168.10.16",client_status="Online"},{client_ip="192.168.16.2",client_status="offline"}})
t:option(DummyValue, "client_ip", translate("IP地址"))
t:option(DummyValue, "client_status", translate("设备状态"))

term = t:option(Button, "delete", translate("删除"))
term.inputstyle = "remove"
function term.write(self, section)
    null, self.tag_error[section] = os.execute("rm /tmp/ac/*")
end

发表在 OpenWRT | 标签为 , , | 留下评论

Ubuntu tftp服务器部署最佳实践

tftp是基于udp的快速文件传输协议,可以用于固件刷机以及文件交换来使用,ubuntu server部署ftp最佳实践操作

TFTP Server服务器端安装

1、安装 tftpd-hpa

sudo apt-get install tftpd-hpa

2、配置tftp服务的根目录,配置文件位于

# /etc/default/tftpd-hpa

内容修改为:

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/opt"  #需要777权限
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure -c -s"

3、然后重启服务生效,服务会自动开机启动,需要用的时候直接将文件放置到 /opt 下面即可

service tftpd-hpa restart

4、这样即使下次整个系统重启tftp服务也会自动跟随启动

TFTP客户端的使用

windows客户端使用

tftp 192.168.10.254 put ipp.txt
tftp 192.168.10.254 get ipp.txt
#最后还可以添加一个重命名为文件名的参数

Linux客户端使用

tftp 192.168.10.254 -c put.ipp.txt 
tftp 912.168.10.254 -c get ipp.txt 
#最后还可以添加一个重命名为文件名的参数

发表在 Linux, Ubuntu | 标签为 , | 留下评论

使用Docker一键部署phpmyadmin

Docker带来的主要方便是:程序自带运行运行环境,不用担心操作系统库的差异,也不需要提前安装运行所需的环境,比如我们部署好了MySQL之后,由不希望安装web服务器和php运行环境,直接使用Docker镜像完成一键部署。

首先我们找到phpmyadmin的镜像:

docker search phpmyadmin

image.png

我们选择第一个镜像,然后运行

docker run -d -e PMA_HOST=rds.ali.com -p 13306:80 phpmyadmin/phpmyadmin

解释一下参数:

-e PMA_HOST 指定要连接的MySQL 数据库HOST

-p 端口映射,将服务器的13306端口映射到容器内的80端口

 

总结:

使用Docker可以快速部署应用,这里运行一个命令,直接部署了MySQL的WEB管理phpmyadmin。



发表在 Docker | 标签为 , | 留下评论