fastjson框架如何處理boolean?CURRENT_TIMESTAMP使用報錯?什麼是 ONLINE DDL 及 pt-online-schema-change ? getBytes引發的亂碼

1、使用fastjson框架進行序列化時,若莫個參數爲Boolean類型,而json裏的值是其它類型時,框架如何處理?html

一、true, false,正常賦值
二、int類型,若爲1,則爲true,不然爲false
三、number類型,若強轉int爲1,則爲true,不然爲false
四、string類型,若爲空串、"null"、"NULL"則爲null;若爲"true","1"則爲true;若爲"false","0"則爲false
四、其它狀況拋錯can not cast to booleanmysql

2、關於CURRENT_TIMESTAMP的問題:
執行如下SQL報錯:git

CREATE TABLE `test` (
`id` bigint(19) NOT NULL AUTO_INCREMENT,
`create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=INNODB;

錯誤:there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
緣由:MYSQL 5.6如下的版本只支持一個字段將當前時間戳爲默認值
四種處理方法:
一、當更新數據時,用觸發器去設置 update_time 爲當前時間
二、當插入數據時,用觸發器去設置 create_time 爲當前時間
三、create_time 設爲 CURRENT_TIMESTAMP,update_time設爲 '0000-00-00 00:00:00',更新、插入時去從新設置更新時間
四、更新MYSQL版本到5.6github

3、什麼是DDL,什麼是ONLINE DDL, 什麼是pt-online-schema-change?
DDL:數據定義語言DDL,用來建立數據庫中的各類對象-----表、視圖、索引、同義詞、聚簇
DML: insert, update, delete
DQL: select
DCL: 授予或回收訪問數據庫的某種特權,並控制數據庫操縱事務發生的時間及效果,對數據庫實行監視sql

MYSQL 5.1的DDL(添加索引):
建新表(包括新加的索引),鎖舊錶,拷數據到新表,改表名,刪舊錶數據庫

MYSQL 5.5,引入FIC(Fast Index Creation):
支持在新增刪除二級索引時,不去新建表,但仍需鎖表json

MYSQL 5.6引入ONLINE DDL:
支持在修改表結構的同時,依然容許DML操做,不是全部DDL操做都支持,具體需參考MYSQL官方文檔:https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl-operations.html服務器

ONLINE DDL的一些限制:
一、不管是涉及到copy table仍是添加索引,都須要保證有足夠的磁盤大小
二、主從結構,主庫在DDL時,會同時執行DML操做,可是從庫因爲是單個SQL THREAD按順序應用log,因此得等ALTER語句執行完,才能夠執行下一條,這時會有主從延遲。
三、在進行 DDL 操做時會保存操做時間內產生的日誌,這與 facebook OSC 的臨時表,可是其保存在內存中,而該內存的大小由參數 innodb_online_alter_log_max_size 定義,默認大小爲 128M,若請求比較頻繁,須要進行調整。
四、ONLINE DDL執行期間,仍會有短期的排它鎖,如準備階段,提交階段。框架

pt-online-schema-change:
第三方工具,支持ONLINE DDLide

pt-online-schema-change 工做過程:
一、建新表
二、新表進行DDL操做
三、原表建立三種觸發器對應insert,update,delete
三、從原表拷貝數據到新表,期間的DML操做,經過觸發器更新到新表
四、鎖原表,改表名
五、刪舊錶

pt-online-schema-change的一些限制:
一、原表不容許有觸發器
二、原表必須有主鍵

 

參考博客:
https://cloud.tencent.com/developer/article/1005177
http://seanlook.com/2016/05/24/mysql-online-ddl-concept/
http://keithlan.github.io/2018/11/23/mysql_online_ddl_inside/

4、關於getBytes方法
背景:

使用第三方SDK,出現中文亂碼,依賴的SDK,有如下代碼:

headers.put(key, Base64Utils.encodeAsString(value.getBytes()));

出錯緣由:
vlaue.getBytes方法,在沒有設置字符集時,會默認以JVM默認的字符集(默認操做系統的字符集)進行處理。而服務器上,操做系統的字符集默認爲US-ASCII,而value其實是UTF-8的,這時候就出現了亂碼狀況。

解決方案:
配置JVM參數,設置JVM默認的字符集爲UTF-8:-Dfile.encoding=UTF-8

分析源碼:

public byte[] getBytes() {
    return StringCoding.encode(value, 0, value.length);
}
static byte[] encode(char[] ca, int off, int len) {
    String csn = Charset.defaultCharset().name();
    try {
        // use charset name encode() variant which provides caching.
        return encode(csn, ca, off, len);
    } catch (UnsupportedEncodingException x) {
        warnUnsupportedCharset(csn);
    }
    try {
        return encode("ISO-8859-1", ca, off, len);
    } catch (UnsupportedEncodingException x) {
        // If this code is hit during VM initialization, MessageUtils is
        // the only way we will be able to get any kind of error message.
        MessageUtils.err("ISO-8859-1 charset not available: " + x.toString());
        // If we can not find ISO-8859-1 (a required encoding) then things
        // are seriously wrong with the installation.
        System.exit(1);
        return null;
    }
}

能夠發如今使用getBytes方法時,默認取使用Charset.defaultCharset()方法來得到字符集
而後再看defaultCharset()方法的源碼

private static volatile Charset defaultCharset;
public static Charset defaultCharset() {
    if (defaultCharset == null) {
        synchronized (Charset.class) {
            String csn = AccessController.doPrivileged(new GetPropertyAction("file.encoding"));
            Charset cs = lookup(csn);
            if (cs != null)
                defaultCharset = cs;
            else
                defaultCharset = forName("UTF-8");
        }
    }
    return defaultCharset;
}

defaultCharset實際上是個單例,JVM啓動後,只會取加載一次file.encoding。而file.encoding在沒有配置的狀況,取的是操做系統的字符集。若想改變默認字符集,則能夠設置JVM參數:-Dfile.encoding=UTF-8

相關文章
相關標籤/搜索