Golang
2021-01-16
官方库里面只看到 PlainAuth 和 CramMd5Auth 两种认证方法。
type loginAuth struct {
username, password string
}
func LoginAuth(username, password string) smtp.Auth {
return &loginAuth{username, password}
}
func (a *loginAuth) Start(server *smtp.ServerInfo) (proto string, toServer []byte, err error) {
return "LOGIN", []byte{}, nil
}
func (a *loginAuth) Next(fromServer []byte, more bool) (toServer []byte, err error) {
if more {
switch strings.ToUpper(string(fromServer)) {
case "USERNAME:":
return []byte(a.username), nil
case "PASSWORD:":
return []byte(a.password), nil
default:
return nil, fmt.Errorf("unknown command %v", fromServer)
}
}
return nil, nil
}
Golang SMTP
2021-01-15
package main
import (
"crypto/tls"
"errors"
"fmt"
"net"
"net/smtp"
)
// ============================================================================
type Transaction struct {
Host string
Port uint16
LocalName string
TlsEnable bool
Username string
Password string
MailFrom string
RcptTo []string
Data []byte
}
func NewTransaction() Transaction {
trans := Transaction{}
return trans
}
func (trans Transaction) Send() error {
addr := fmt.Sprintf("%s:%d", trans.Host, trans.Port)
// SendMail(addr string, a Auth, from string, to []string, msg []byte) error
c, err := smtp.Dial(addr)
if err != nil {
return err
}
defer c.Close()
c.Hello(trans.LocalName)
if ok, _ := c.Extension("STARTTLS"); ok {
serverName, _, _ := net.SplitHostPort(addr)
config := &tls.Config{
InsecureSkipVerify: true,
ServerName: serverName,
}
if err = c.StartTLS(config); err != nil {
return err
}
} else {
fmt.Printf("smtp: server doesn't support STARTTLS\n")
}
if trans.Username != "" {
if ok, _ := c.Extension("AUTH"); !ok {
return errors.New("smtp: server doesn't support AUTH")
}
auth := smtp.PlainAuth("", trans.Username, trans.Password, trans.Host)
if err = c.Auth(auth); err != nil {
fmt.Println("smtp: authentication failed")
return err
}
}
if err = c.Mail(trans.MailFrom); err != nil {
return err
}
for _, addr := range trans.RcptTo {
if err = c.Rcpt(addr); err != nil {
return err
}
}
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(trans.Data)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
return c.Quit()
}
// ============================================================================
func main() {
from := "ninedoors@126.com"
to := "ninedoors@qq.com"
msg := []byte{}
fmt.Println("============================================================")
trans := Transaction{
"smtp.126.com", 25, "peach", false,
from, "password",
from, []string{to},
msg,
}
trans.Send()
}
net/smtp
没有发现有好的日志实现,我只能定制了一个版本实现了日志
smtp.Client
-> textproto.Conn
-> textproto.Writer
HTTPS TLS 信息安全
2021-01-08
MySQL DB
2021-01-06
通过 apt 和 apt-file 列出 mysql 提供的所有可执行文件。
DB MySQL
2021-01-06
历史
- 在更早的 20 年间,MySQL 的前身 UNIREG 被 Monty 开发
- 1994 年瑞典公司 TcX 成立,Monty 是三位创始人之一。次年,这家公司改名为 MySQL AB。
TcX 将 UNIREG 改造为一款支持 SQL 的关系型数据库。
- 1995 年,MySQL 3.11 发布。
- 1999 年,MySQL 3.23 集成 BDB,开始了可插拔存储引擎架构。
- 2000 年,ISAM 改良成 MyISAM,同时 MySQL 基于 GPL 协议开源。
- 2001 年,MySQL AB 和芬兰公司 Infobase Oy 合作,为 MySQL 3.22 带来了 InnoDB 引擎。
重点是事务和行级锁。
注意:InnoDB 是 GPL / 专有协议双授权。
- 2005 年,Innobase Oy 被甲骨文收购。同年, MySQL 5.0 发布。
注意:我们现在数据库系统课的很多概念,触发器,存储过程,视图,游标等都是 5.0 开始支持的。
- 2006 年,Oracle 曾经试图收购 MySQL 但是遭到拒绝。
- 2008-02-26 MySQL AB 被 SUN 10 亿美元收购。
- 2008-11-27 MySQL 5.1,开始支持分区,和主从同步时的行复制(RBR)。
- 2009-04-20 SUN 被甲骨文 74 亿美元收购,收购直到 2010-01-27 才完成。
最重要的存储引擎 InnoDB 终于和 MySQL 版权归于一处了。
- 2010-12-03 MySQL 5.5,InnoDB 成为默认引擎(5.5.5 开始)。
- innodb 改进
- utf8mb4
- metadata lock
- 2013-02-05 MySQL 5.6
- 2015-10-21 MySQL 5.7
- 2018-04-19 MySQL 8.0
- 最新版本是
2020-10-19 发布的 8.0.22
2021-10-19 发布的 8.0.27 (Update @ 2021-11-16)
说明:
- 5.6,5.7 应该是现在最常用的两个版本。
8.0 还比较新,我还没有在线上业务中用过。但是有很多我感兴趣的特性。
- 列举的特性可能是在不同子版本引入,开发中可能需要留意不同子版本的差异。
就现在我理解的主流开发思想,对组件应该简单应用,就数据库而言,应该只用来做基础存储,不要涉及复杂功能,不要涉及所谓特性,最要用好几个大版本就在的功能,其他数据库系统都有的功能。
我觉得有点过了。这个另说吧。
MySQL 5.6 新特性
复制和日志(replication)
1)支持延时复制,MySQL现在支持延迟复制,默认是0秒。使用CHANGE MASTER TO参数 MASTER_DELAY 来设置延迟。可以让slave跟master之间控制一个时间间隔,方便特殊情况下的数据恢复。(以前是使用第三方工具可以做到) 2)行级复制功能加强,可以降低磁盘、内存、网络等资源开销(只记录能确定行记录的字段即可)。3)现在支持多线程复制。如果开启,sql线程作为协调者协调多个工作线程,数量取决于slave_parallel_workers。现在多线程复制以单库为基础,特定库的更新的相对顺序和主库一样。不过,没有必要协调不同库之间的事务。事务可以被分布到每个库,意味着一个复制从库的工作线程可以顺序执行事务而不必等待其它库的更新完成。4)支持以全局统一事务ID(GTID)为基础的复制。当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务。GTID复制是全部以事务为基础,使得检查主从一致性变得非常简单。如果所有主库上提交的事务也同样提交到从库上,一致性就得到了保证。5)支持启用GTID,对运维人员来说应该是一件令人高兴的事情,在配置主从复制,传统的方式里,你需要找到binlog和POS点,然后change master to指向,而不是很有经验的运维,往往会将其找错,造成主从同步复制报错,在mysql5.6里,如果使用了GTIDs,启动一个新的复制从库或切换到一个新的主库,就不必依赖log文件或者pos位。需要知道master的IP、端口,账号密码即可,因为同步复制是自动的,mysql通过内部机制GTID自动找点同步。
6)binlog的读写现在是崩溃安全的,因为只有完整的事件(或者事务)才会被记录和读取。默认会记录事件的大小以及事件本身,使用大小来验证事件被正确记录。你也可以使用参数binlog_checksum设置使用crc32记录事件的校验值。使用参数master_verify_checksum可以让服务读取校验值。slave-sql-verify-checksum参数使从库读relay日志的时候读取校验值。
MySQL支持在表中保存主库连接信息了。使用参数–master-info-repository和 –relay-log-info-repository来设置。设置 –master-info-repository为表,会记录连接信息到slave_master_info表。设置–relay-log-info-repository为表,会记录relay log信息到slave_relay_log_info表。这几个表都是自动建立在mysql系统库。
增强Performance Schema数据库(Mysql performance schema)
1)记录表的输入与输出,操作包括行级访问表和临时表,如insert,upate,delete. 2)表的事件过滤,以库或者表名为基础。3)线程的事件过滤,更多关于线程的信息被搜集4)表和索引I/O以及表锁的统计表。5)记录命令以及命令的阶段。
不允许在存储过程中或者函数参数中或者存储程序本地变量中使用default来指定(如:SET var_name = DEFAULT命令),但可以在指定系统变量时使用default。
MySQL 5.7 新特性
- 引入对 JSON 的支持,JSON 类型和相关函数。
组复制
InnoDB Cluster
多源复制
增强半同步(AFTER_SYNC)
基于WRITESET的并行复制。
在线开启GTID复制。
在线设置复制过滤规则。
在线修改Buffer pool的大小。
在同一长度编码字节内,修改VARCHAR的大小只需修改表的元数据,无需创建临时表。
可设置NUMA架构的内存分配策略(innodb_numa_interleave)。
透明页压缩(Transparent Page Compression)。
UNDO表空间的自动回收。
查询优化器的重构和增强。
可查看当前正在执行的SQL的执行计划(EXPLAIN FOR CONNECTION)。
引入了查询改写插件(Query Rewrite Plugin),可在服务端对查询进行改写。
EXPLAIN FORMAT=JSON会显示成本信息,这样可直观的比较两种执行计划的优劣。
引入了虚拟列,类似于Oracle中的函数索引。
新实例不再默认创建test数据库及匿名用户。
引入ALTER USER命令,可用来修改用户密码,密码的过期策略,及锁定用户等。
mysql.user表中存储密码的字段从password修改为authentication_string。
表空间加密。
优化了Performance Schema,其内存使用减少。
Performance Schema引入了众多instrumentation。常用的有Memory usage instrumentation,可用来查看MySQL的内存使用情况,Metadata Locking Instrumentation,可用来查看MDL的持有情况,Stage Progress instrumentation,可用来查看Online DDL的进度。
同一触发事件(INSERT,DELETE,UPDATE),同一触发时间(BEFORE,AFTER),允许创建多个触发器。在此之前,只允许创建一个触发器。
InnoDB原生支持分区表,在此之前,是通过ha_partition接口来实现的。
分区表支持可传输表空间特性。
集成了SYS数据库,简化了MySQL的管理及异常问题的定位。
原生支持JSON类型,并引入了众多JSON函数。
引入了新的逻辑备份工具-mysqlpump,支持表级别的多线程备份。
引入了新的客户端工具-mysqlsh,其支持三种语言:JavaScript, Python and SQL。两种API:X DevAPI,AdminAPI,其中,前者可将MySQL作为文档型数据库进行操作,后者用于管理InnoDB Cluster。
mysql_install_db被mysqld --initialize代替,用来进行实例的初始化。
原生支持systemd。
引入了super_read_only选项。
可设置SELECT操作的超时时长(max_execution_time)。
可通过SHUTDOWN命令关闭MySQL实例。
引入了innodb_deadlock_detect选项,在高并发场景下,可使用该选项来关闭死锁检测。
引入了Optimizer Hints,可在语句级别控制优化器的行为,如是否开启ICP,MRR等,在此之前,只有Index Hints。
GIS的增强,包括使用Boost.Geometry替代之前的GIS算法,InnoDB开始支持空间索引。
MySQL 8.0 新特性
最重要的是窗口函数和 CTE
- 窗口函数,这个功能补齐了,非常香。
- CTE (Common Table Expressions)
- 递归 SQL
- UTF8 的变更,默认的 UTF8 字符集是 UTF8MB4
- 优化和完善了对 JSON 的支持,最重要的是 JSON Partial Updates,支持对 JSON 的局部更新。
其他MySQL 8.0计划更新的特性包括:
在锁定行方面增加了更多选项,如SKIP LOCKED和NOWAIT两个选项。其中,
SKIP LOCKED允许在操作中不锁定那些需要忽略的行;NOWAIT则在遇到行的锁定的时候马上抛出错误。
MySQL能根据可用内存的总量去伸缩扩展,以更好利用虚拟机的部署。
新增“隐藏索引”的特性,这样索引可以在查询优化器中变为不可见。索引在标记为不可用后,和表的数据更改同步,但是优化器不会使用它们。对于使用隐藏索引的建议,是当不决定某个索引是否需要保留的时候,可以使用。
引入了原生的,基于InnoDB的数据字典。数据字典表位于mysql库中,对用户不可见,同mysql库的其它系统表一样,保存在数据目录下的mysql.ibd文件中。不再置于mysql目录下。
Atomic DDL。
重构了INFORMATION_SCHEMA,其中,部分表已重构为基于数据字典的视图,在此之前,其为临时表。
PERFORMANCE_SCHEMA查询性能提升,其已内置多个索引。
不可见索引(Invisible index)。
降序索引。
直方图。
角色(Role)。
资源组(Resource Groups),可用来控制线程的优先级及其能使用的资源,目前,能被管理的资源只有CPU。
引入了innodb_dedicated_server选项,可基于服务器的内存来动态设置innodb_buffer_pool_size,innodb_log_file_size和innodb_flush_method。
快速加列(ALGORITHM=INSTANT)。
自增主键的持久化。
可持久化全局变量(SET PERSIST)。
默认字符集由latin1修改为utf8mb4。
默认开启UNDO表空间,且支持在线调整数量(innodb_undo_tablespaces)。在MySQL 5.7中,默认不开启,若要开启,只能初始化时设置。
备份锁。
Redo Log的优化,包括允许多个用户线程并发写入log buffer,可动态修改innodb_log_buffer_size的大小。
默认的认证插件由mysql_native_password更改为caching_sha2_password。
默认的内存临时表由MEMORY引擎更改为TempTable引擎,相比于前者,后者支持以变长方式存储VARCHAR,VARBINARY等变长字段。从MySQL 8.0.13开始,TempTable引擎支持BLOB字段。
Grant不再隐式创建用户。
SELECT ... FOR SHARE和SELECT ... FOR UPDATE语句中引入NOWAIT和SKIP LOCKED选项,解决电商场景热点行问题。
正则表达式的增强,新增了4个相关函数,REGEXP_INSTR(),REGEXP_LIKE(),REGEXP_REPLACE(),REGEXP_SUBSTR()。
查询优化器在制定执行计划时,会考虑数据是否在Buffer Pool中。而在此之前,是假设数据都在磁盘中。
ha_partition接口从代码层移除,如果要使用分区表,只能使用InnoDB存储引擎。
引入了更多细粒度的权限来替代SUPER权限,现在授予SUPER权限会提示warning。
GROUP BY语句不再隐式排序。
MySQL 5.7引入的表空间加密特性可对Redo Log和Undo Log进行加密。
information_schema中的innodb_locks和innodb_lock_waits表被移除,取而代之的是performance_schema中的data_locks和data_lock_waits表。
引入performance_schema.variables_info表,记录了参数的来源及修改情况。
增加了对于客户端报错信息的统计(performance_schema.events_errors_summary_xxx)。
可统计查询的响应时间分布(call sys.ps_statement_avg_latency_histogram())。
支持直接修改列名(ALTER TABLE ... RENAME COLUMN old_name TO new_name)。
用户密码可设置重试策略(Reuse Policy)。
移除PASSWORD()函数。这就意味着无法通过“SET PASSWORD ... = PASSWORD('auth_string') ”命令修改用户密码。
代码层移除Query Cache模块,故Query Cache相关的变量和操作均不再支持。
BLOB, TEXT, GEOMETRY和JSON字段允许设置默认值。
可通过RESTART命令重启MySQL实例。
参考资料与拓展阅读
日志 Graylog
2021-01-06
ssh // 包含 ssh
ssh login // 包含 ssh 或者 login
"ssh login" // 包含 ssh login
// 正则匹配
/ethernet[0-9]+/
type:(ssh OR login) // 字段 type 包含 ssh 或者 login
// 必须 (不) 包含字段
_exists_:type
NOT _exists_:type
// 支持 `*`, `?` 两种通配符
source:xxx?yyy
source:xxx*yyy
// PS: 默认配置,通配符不能放在最前面,避免内存消耗太多
// 可以这样开启:
// allow_leading_wildcard_searches = true
// 模糊匹配 ~
ssh logni~ // 可以搜索到 ssh login
"foo bar"~5 // Damerau–Levenshtein distance
// 范围
http_response_code:[500 TO 504]
http_response_code:{400 TO 404}
bytes:{0 TO 64]
http_response_code:[0 TO 64}
// 大小
http_response_code:>400
http_response_code:<400
http_response_code:>=400
http_response_code:<=400
http_response_code:(>=400 AND <500)
// 时间范围
timestamp:["2019-07-23 09:53:08.175" TO "2019-07-23 09:53:08.575"]
otherDate:[now-5d TO now-4d]
此外,还有 AND,OR,NOT,括号等逻辑运算符可用。
转义符:
& | : \ / + - ! ( ) { } [ ] ^ " ~ * ?
参考资料与拓展阅读
DB MySQL
2021-01-06
SHOW VARIABLES LIKE '%engine%';
SHOW ENGINES;
以 MySQL 8.0 为例:
除了 PERFORMANCE_SCHEMA,
Engine |
Support |
Comment |
Transactions |
XA |
Savepoints |
ARCHIVE |
YES |
Archive storage engine |
NO |
NO |
NO |
BLACKHOLE |
YES |
/dev/null storage engine (anything you write to it disappears) |
NO |
NO |
NO |
MRG_MYISAM |
YES |
Collection of identical MyISAM tables |
NO |
NO |
NO |
FEDERATED |
NO |
Federated MySQL storage engine |
NULL |
NULL |
NULL |
MyISAM |
YES |
MyISAM storage engine |
NO |
NO |
NO |
InnoDB |
DEFAULT |
Supports transactions, row-level locking, and foreign keys |
YES |
YES |
YES |
MEMORY |
YES |
Hash based, stored in memory, useful for temporary tables |
NO |
NO |
NO |
CSV |
YES |
CSV storage engine |
NO |
NO |
NO |
Percona (8.0) 和 MySQL 保持一致,不过 InnoDB 实际被替换成他们自己开发的兼容引擎 XtraDB。
MariaDB (10.1.45) 也使用 XtraDB 替换了 InnoDB,而且没有 BLACKHOKE, ARCHIVE,但是多了:
Engine |
Support |
Comment |
Transactions |
XA |
Savepoints |
TokuDB |
DEFAULT |
Percona TokuDB Storage Engine with Fractal Tree(tm) Technology |
YES |
YES |
YES |
SEQUENCE |
YES |
Generated tables filled with sequential values |
YES |
NO |
YES |
Aria |
YES |
Crash-safe tables with MyISAM heritage |
NO |
NO |
NO |
MyISAM
在 2010 年发布的 MySQL 5.5.5 之前,一直是 MySQL 的默认引擎。
InnoDB
InnoDB 是甲骨文的。
TokuDB
TokuTek 公司开发,后来被 Percona 公司收购,现在已被 Percona 废弃(仓库归档)。
其他
- Blackhole
- Mrg_MyISAM
- Memory
- CSV
- Archive
第三方
参考资料与拓展阅读
存储 对象存储
2021-01-05
数据校验 JSONSchema
2021-01-03
JSON Schema 是一个 JSON 数据的校验规范,其规则的定义本身也是 JSON 格式。
目前有 RFC 草案。最新是 2022-06-10 提交的 draft-bhutton-json-schema-01。
Update @ 2023-02-28: 现在还是没有成为标准。最新的那份草案早已过期(提交之后半年)。
- JSON Schema: A Media Type for Describing JSON Documents
- JSON Schema Validation: A Vocabulary for Structural Validation of JSON
- Relative JSON Pointers
示例
{
"type": "object",
"properties": {
"number": { "type": "number" },
"street_name": { "type": "string" },
"street_type": {
"type": "string",
"enum": ["Street", "Avenue", "Boulevard"]
}
}
}
关键字
数据类型(type 关键字)
string
字符串
integer
整数
number
数字,包括整数、浮点数
boolean
布尔类型:true
,false
object
对象
array
数组
null
空值
字符串
数值(number,integer)
minimum
大于等于
exclusiveMinimum
大于,部分版本中,这个值是 bool 型
maximum
小于等于
exclusiveMaximum
小于,部分版本中,这个值是 bool 型
multipleOf
倍数
对象
- properties
- patternProperties
- additionalProperties
数组
- items
- additionalItems
- minItems 整数
- maxItems 整数
- uniqueItems 布尔
通用规则
- title
- description
- default
- required 必需
- enum
- const
- anyOf, oneOf, allOf
Python 示例
采用 Julian/jsonschema
PS:现在仓库地址转向了 python-jsonschema/jsonschema
>>> from jsonschema import validate
>>> # A sample schema, like what we'd get from json.load()
>>> schema = {
... "type" : "object",
... "properties" : {
... "price" : {"type" : "number"},
... "name" : {"type" : "string"},
... },
... }
>>> # If no exception is raised by validate(), the instance is valid.
>>> validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema)
>>> validate(
... instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema,
... ) # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
ValidationError: 'Invalid' is not of type 'number'
参考资料与拓展阅读
Kodi 智能电视 XBMC 电视盒子
2021-01-01
了解一下现在热门的智能电视方案 Kodi。
Android TV、Boxee、火狐操作系统、Frog、谷歌电视、Horizon TV、httvLink,、Inview、Kodi Entertainment Center、MeeGo、Mediaroom,、OpenTV,、Opera TV,、Plex,、Roku,、RDK(Reference Development Kit)、智能电视联盟(英文原文:Smart TV Alliance), ToFu Media Platform,、Ubuntu TV以及雅虎智能电视这些平台均由私立机构进行管理。混合广播宽带电视(HbbTV)由混合广播宽带电视协会(英文原文:Hybrid Broadcast Broadband TV association)、CE-HTML是 面向消费类电子产品的网络(英文缩写:Web4CE)的一部分、开放互联网电视论坛(英文缩写:OIPF,英文全称:Open IPTV Forum)是混合广播宽带电视的一部分,还有Tru2way商业化的软件开发平台。
Kodi
https://kodi.tv/
https://en.wikipedia.org/wiki/Kodi_(software)
官网上的定位是 The ultimate entertainment center, 终极娱乐中心。
2002 Xbox Media Player
2004 Xbox Media Center (XBMC)
2008 XBMC 放弃了对 Xbox 的支持
2014 Kodi (从 v14 开始),因为定位已经改成娱乐中心,不再局限于媒体播放,此外,还有商标方面的问题。
https://en.wikipedia.org/wiki/List_of_software_based_on_Kodi_and_XBMC
- OpenELEC: Open Embedded Linux Entertainment Center
2017 年之后就没有更新了,主要开发者早已陆续转入了 LibreELEC 项目
- LibreELEC
- CoreELEC
其他的产品
Android TV
Apple TV
Amazon Fire TV: 基于 Android TV
Roku OS
SambaTV
三星Tizen
LG WebOS
Panasonic My Home Screen: 基于 Firefox OS
又看到一个项目:
https://plasma-bigscreen.org/zh-cn/