1. Security
MongoDB提供了一系列的保護措施,以保護它自身安全:
- 啓用訪問控制並實行身份驗證
- MongoDB支持多種身份認證機制,默認的認證機制是SCRAM
- 配置基於角色的訪問控制
- 首先創建一個管理員賬號(administrator),然後創建其他賬號。爲每個訪問系統的人和應用程序創建一個唯一的MongoDB賬號
- 遵循最小特權原則。創建定義一組用戶所需訪問權限的角色。然後創建用戶,並僅爲他們分配執行操作所需的角色。用戶可以是人,也可以是客戶端應用程序
- 一個用戶可以擁有跨不同數據庫的權限。如果一個用戶需要在多個數據庫上的權限,請創建一個具有授予適用數據庫權限的角色的用戶,而不是在不同的數據庫中多次創建該用戶
- 加密通信(TLS/SSL)加密和保護數據
- 將 MongoDB 配置爲對所有輸入和輸出連接使用 TLS/SSL
- 限制網絡暴露
- 確保MongoDB運行在受信任的網絡環境中,並配置防火牆或安全組來控制MongoDB實例的入站和出站流量
- 禁用直接SSH root訪問
- 僅允許受信任的客戶端訪問 MongoDB 實例可用的網絡接口和端口
- 審計系統活動
- 跟蹤對數據庫配置和數據的訪問和更改
- 使用專用用戶運行MongoDB使用安全配置選項運行MongoDB
- 使用專用操作系統用戶帳戶運行 MongoDB 進程。確保該帳戶具有訪問數據的權限,但沒有不必要的權限
1.1. Authentication(認證)
Authentication 是驗證用戶的身份
Authorization 授予用戶對資源和操作的訪問權限
簡而言之,認證是告訴我“你是誰”,授權是“你可以做什麼”
訪問控制很簡單,只有三步:
- 啓用訪問控制
- 創建用戶
- 認證用戶
Salted Challenge Response Authentication Mechanism (SCRAM) 是 MongoDB 的默認身份驗證機制。
當用戶進行身份驗證時,MongoDB使用SCRAM根據用戶名、密碼和身份驗證數據庫 驗證提供的用戶憑據。
MongoDB支持兩種SCRAM機制:SCRAM-SHA-1 和 SCRAM-SHA-256
以下是單機版mongod實例進行SCRAM認證的步驟:
1、不帶訪問控制啓動MongoDB
mongod --port 27017 --dbpath /var/lib/mongodb
2、連接到mongodb實例
mongosh --port 27017
3、創建 administrator 用戶
注意:可以在啓用訪問控制之前或之後創建用戶管理員。如果在創建任意用戶之前啓用了訪問控制,那麼MongoDB會返回一個localhost異常,這個異常告訴我們允許在admin數據庫中創建管理員用戶。創建之後,必須作爲用戶管理員進行身份驗證後,纔可以再創建其他用戶。
(PS:上面這句話的意思是,在啓用訪問控制之前或者之後創建用戶管理員都可以,但是如果先啓用了訪問控制,而後再創建用戶的時候就會報錯。這個錯會告訴我們,應該首先在admin數據庫中創建用戶管理員,然後用用戶管理員登錄(或者叫身份驗證)成功以後纔可以再創建其它用戶。)
具體操作步驟如下:
(1)切換到admin數據庫
(2)添加一個myUserAdmin用戶,並賦予其“userAdminAnyDatabase”和“readWriteAnyDatabase”這兩個角色
use admin
db.createUser(
{
user: "myUserAdmin",
pwd: passwordPrompt(), // or cleartext password
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
}
)
注意:passwordPrompt()方法提示你輸入密碼。你也可以直接將密碼指定爲字符串。建議使用passwordPrompt()方法,以避免在屏幕上看到密碼,並可能將密碼泄露到shell歷史記錄中。
userAdminAnyDatabase 角色運行用戶:
- 創建用戶
- 授予或撤銷用戶角色
- 創建或修改自定義角色
4、帶訪問控制,重啓MongoDB實例
用 mongosh 關閉 mongod 實例
db.adminCommand( { shutdown: 1 } )
啓動mongod,這次帶上訪問控制
- 如果從命令行啓動mongod,則只需帶上 --auth 參數即可
mongod --auth --port 27017 --dbpath /var/lib/mongodb
- 如果從配置文件啓動mongod,則只需將配置文件中security.authorization設置爲enabled即可,然後 systemctl start mongod
security:
authorization: enabled
5、以用戶管理員身份連接和認證
方式一:連接的時候進行認證
用 mongosh 連接,帶上 -u <username>, -p 和 --authenticationDatabase <database> 命令行參數
mongosh --port 27017 --authenticationDatabase "admin" -u "myUserAdmin" -p
隨後,輸入正確的密碼即可連接成功
方式二:連接之後再進行認證
先連接,然後切換到認證數據庫(本例中是admin),然後使用db.auth(<username>, <pwd>) 方法進行認證
mongosh --port 27017
use admin
db.auth("myUserAdmin", passwordPrompt()) // or cleartext password
1.2. 基於角色的訪問控制
MongoDB默認情況下沒有啓用訪問控制。可以通過 --auth 命令行參數 或者 將配置文件中security.authorization設置爲enabled 來啓用訪問控制。
一個角色可以從它所屬數據庫中的其他角色那裏繼承權限。 在 admin 數據庫上創建的角色可以從任何數據庫中的角色繼承權限。
分配了角色的用戶將獲得該角色的所有權限。一個用戶可以有多個角色。通過分配給不同數據庫中的用戶角色,在一個數據庫中創建的用戶可以具有操作其他數據庫的權限。
注意:在數據庫中創建的第一個用戶應該是具有管理其他用戶權限的用戶管理員。
1.2.1. 內置角色
每個MongoDB的內置角色都定義了角色數據庫中所有非系統集合的數據庫級別的訪問權限以及所有系統集合的集合級別的訪問權限。
MongoDB爲每個數據庫提供內置的數據庫用戶和數據庫管理角色。MongoDB僅在admin數據庫上提供所有其他內置角色。
角色類型 | 角色名稱 | 角色描述 |
---|---|---|
Database User Roles | read | 提供在所有非系統集合和system.js集合中讀取數據的能力。 |
readWrite | 提供“read”角色的所有權限,外加在所有非系統集合和system.js集合中修改數據的能力。 | |
Database Administration Roles | dbAdmin | 提供執行管理任務的能力,例如與數據庫相關的任務、索引和收集統計信息。該角色不授予用戶和角色管理權限。 |
dbOwner | 數據庫所有者可以對數據庫執行任何管理操作。該角色結合了readWrite、dbAdmin和userAdmin三個角色的權限。 | |
userAdmin | 提供在當前數據庫上創建和修改角色和用戶的能力。 | |
Cluster Administration Roles | clusterAdmin | 提供最大的集羣管理訪問。此角色結合了 clusterManager、clusterMonitor 和 hostManager 角色授予的權限。此外,該角色還提供 dropDatabase 操作的權限。 |
clusterManager | 提供對集羣的管理和監控操作的權限 | |
clusterMonitor | 提供對監控工具的只讀訪問權限 | |
hostManager | 提供監控和管理服務器的能力 | |
Backup and Restoration Roles | backup | 提供備份數據所需的最低權限 |
restore | 提供從備份中恢復數據所需的權限 | |
All-Database Roles | readAnyDatabase | 提供和“read”角色相似的在所有數據庫上的只讀權限,local和config數據庫除外 |
readWriteAnyDatabase | 提供和“readWrite”角色相似的在所有數據庫上的讀寫權限,local和config數據庫除外 | |
userAdminAnyDatabase | 提供和“userAdmin”角色相似的在所有數據庫上訪問用戶管理操作的權限,local和config數據庫除外 | |
dbAdminAnyDatabase | 提供和“dbAdmin”角色相似的在所有數據庫上管理操作的權限,local和config數據庫除外 | |
Superuser Roles | root |
超級用戶,提供以下角色的所有權限:
|
Internal Role | __system | MongoDB 將此角色分配給代表集羣成員的用戶對象,例如副本集成員和 mongos 實例。 |
1.2.2. 自定義角色
1.2.3. 管理用戶和角色
連接
mongosh --port 27017 -u myUserAdmin -p 'abc123' --authenticationDatabase 'admin'
創建角色
use admin
db.createRole(
{
role: "mongostatRole",
privileges: [
{ resource: { cluster: true }, actions: [ "serverStatus" ] }
],
roles: []
}
)
查看用戶角色
db.getUser("zhangsan")
查看角色權限
db.getRole( "readWrite", { showPrivileges: true } )
回收(撤銷)角色
use reporting
db.revokeRolesFromUser(
"reportsUser",
[
{ role: "readWrite", db: "accounts" }
]
)
授予角色
db.grantRolesToUser(
"reportsUser",
[
{ role: "read", db: "accounts" }
]
)
創建用戶
use test
db.createUser(
{
user:"user123",
pwd: passwordPrompt(), // or cleartext password
roles:[ "readWrite", { role:"changeOwnPasswordCustomDataRole", db:"admin" } ]
}
)
修改密碼
db.changeUserPassword("reporting", "SOh3TbYhxuLiW8ypJPxmt1oOfL")
或者
use test
db.updateUser(
"user123",
{
pwd: passwordPrompt(), // or cleartext password
customData: { title: "Senior Manager" }
}
)
認證
db.auth( <username> )
db.auth( <username>, passwordPrompt() )
db.auth( <username>, <password> )
2. MongoDB Shell
2.1. 安裝 mongosh
下載安裝包,然後解壓,並設置環境變量
# 解壓
tar -zxvf mongosh-1.1.7-linux-x64.tgz
# 授予執行權限
chmod +x bin/mongosh
chmod +x bin/mongocryptd-mongosh
# 添加到PATH環境變量中
sudo cp mongosh /usr/local/bin/
sudo cp mongocryptd-mongosh /usr/local/bin/
# 或者
sudo ln -s $(pwd)/bin/* /usr/local/bin/
2.2. 連接到MongoDB服務器
1、本地實例,默認端口
mongosh
等同於
mongosh "mongodb://localhost:27017"
以上兩種寫法是一樣的
2、本地實例,非默認端口
mongosh --port 28015
等價於
mongosh "mongodb://localhost:28015"
這兩種寫法是一樣的
3、遠程實例
mongosh --host mongodb0.example.com --port 28015
或者
mongosh "mongodb://mongodb0.example.com:28015"
2.2.1. 選項參數
1、如果要連接到的MongoDB實例需要身份驗證,那麼可以使用 --username 和 --authenticationDatabase 命令行選項。mongosh 會提示你輸入密碼,它會在你鍵入時屏蔽該密碼。
例如:
mongosh "mongodb://mongodb0.example.com:28015" --username alice --authenticationDatabase admin
也可以加上 --password 選項,這樣的話就是以明文方式帶上密碼
2、連接到副本集
# 連接到副本集
mongosh "mongodb://mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017/?replicaSet=replA"
3、連接到指定的數據庫
下面的連接字符串URI將連接到數據庫db1
mongosh "mongodb://localhost:27017/db1"
2.3. mongosh 用法
# 顯示當前數據庫
db
# 切換數據庫
use <database>
# 創建一個新的數據庫和集合
# 如果集合不存在,MongoDB 會在首次存儲該集合的數據時創建該集合
use myNewDatabase
db.myCollection.insertOne( { x: 1 } );
1、向集合中插入數據
db.myCollection.insertOne()
其中:
- db 代表當前數據庫
- myCollection 是集合的名稱
2、查看數據庫中的集合
db.getCollection()
3、終止命令行
Ctrl + C
4、清屏
cls
或者
Ctrl + L
5、文檔的增刪查改
# 插入單條文檔
db.collection.insertOne()
# 插入多條文檔
db.collection.insertMany()
# 查詢所有文檔
db.collection.find()
# 帶查詢條件
db.collection.find({<field>:<value>, <field>:<value>, ...})
# 更新單條文檔
db.collection.updateOne()
# 更新多條文檔
db.collection.updateMany()
# 替換
db.collection.replaceOne()
# 刪除單條文檔
db.collection.deleteOne()
# 刪除多條文檔
db.collection.deleteMany()
示例
use example
db.movies.insertOne(
{
title: "The Favourite",
genres: [ "Drama", "History" ],
runtime: 121,
rated: "R",
year: 2018,
directors: [ "Yorgos Lanthimos" ],
type: "movie"
}
)
db.movies.find( { title: "The Favourite" } )
db.movies.find( {
year: 2010,
$or: [ { "awards.wins": { $gte: 5 } }, { genres: "Drama" } ]
} )
db.listingsAndReviews.updateMany(
{ security_deposit: { $lt: 100 } },
{
$set: { security_deposit: 100, minimum_nights: 1 }
}
)
db.movies.find( { rated: { $in: [ "PG", "PG-13" ] } } )
db.movies.deleteMany({})
db.movies.deleteMany( { title: "Titanic" } )
2.4. mongosh Help
1、命令行幫助
mongosh --help
2、mongosh Shell 幫助
help
3、數據庫幫助
show dbs
db.help()
4、集合幫助
(1)查看當前數據庫下的集合
show collections
(2)查看集合對象幫助
db.collection.help()
(3)查看特定方法的幫助,用 db.<collection>.<method>.help()
db.collection.getIndexes.help()
(4)光標幫助
db.collection.find().help()
更多參見
https://docs.mongodb.com/mongodb-shell/reference/methods/
https://docs.mongodb.com/mongodb-shell/reference/options/
3. 數據庫、集合、文檔
在 MongoDB 中,數據庫保存一個或多個文檔集合。
通過 use <db> 來選擇某一個數據使用
如果數據庫不存在,MongoDB 會在首次存儲該數據庫的數據時創建該數據庫。
use myNewDB
db.myNewCollection1.insertOne( { x: 1 } )
MongoDB 將文檔存儲在集合中。 集合類似於關係型數據庫中的表。
如果集合不存在,MongoDB 會在首次存儲該集合的數據時創建該集合。
db.myNewCollection2.insertOne( { x: 1 } )
db.myNewCollection3.createIndex( { y: 1 } )
MongoDB 將數據記錄存儲爲 BSON 文檔。BSON 是 JSON 文檔的二進制表示,儘管它包含比 JSON 更多的數據類型。
文檔結構
{
field1: value1,
field2: value2,
field3: value3,
...
fieldN: valueN
}
字段的值可以是任何 BSON 數據類型,包括其他文檔、數組和文檔數組。例如,以下文檔包含不同類型的值:
var mydoc = {
_id: ObjectId("5099803df3f4948bd2f98391"),
name: { first: "Alan", last: "Turing" },
birth: new Date('Jun 23, 1912'),
death: new Date('Jun 07, 1954'),
contribs: [ "Turing machine", "Turing test", "Turingery" ],
views : NumberLong(1250000)
}
字段名稱是字符串,但是有以下限制
- 字段名“_id”被保留用作主鍵,它的值在集合中必須是唯一的,是不可變的,並且可以是數組以外的任何類型。 如果 _id 包含子字段,則子字段名稱不能以 ($) 符號開頭。
- 字段名稱不能包含null字符
- 服務器允許存儲包含點 (.) 和美元符號 ($) 的字段名稱。
點符號
MongoDB 使用點(.)符號來訪問數組的元素和訪問嵌入文檔的字段。
數組
"<array>.<index>"
例如:
{
...
contribs: [ "Turing machine", "Turing test", "Turingery" ],
...
}
要指定 contribs 數組中的第三個元素,請使用點表示法“contribs.2”
內嵌文檔
"<embedded document>.<field>"
例如:
{
...
name: { first: "Alan", last: "Turing" },
contact: { phone: { type: "cell", number: "111-222-3333" } },
...
}
- 要指定“first”字段,可以使用“name.last”
- 要指定“number”字段,可以使用“contact.phone.number”
字段順序
與 JavaScript 對象不同,BSON 文檔中的字段是有序的。
對於查詢操作,在比較文檔時,字段排序非常重要。
例如,在文檔查詢中比較a和b兩個字段時,{a: 1, b: 1} 與 {b: 1, a: 1} 是不同的。
對於寫入操作,MongoDB 保留文檔字段的順序,但以下情況除外:
- _id 字段始終是文檔中的第一個字段
- 包含重命名字段名稱的更新操作可能會導致文檔中的字段重新排序
BJSON類型
https://docs.mongodb.com/manual/reference/bson-types/
ObjectId
ObjectId 很小,可能是唯一的,生成速度快,並且是有序的。 ObjectId 值的長度爲 12 個字節,包括:
- 一個4字節的時間戳,表示ObjectId的創建時間
- 一個5字節的隨機值,每個進程生成一次
- 一個3字節的遞增計數器,初始化爲一個隨機值
在MongoDB中,存儲在集合中的每個文檔都需要一個唯一的_id字段作爲主鍵。如果插入的文檔省略了_id字段,MongoDB會自動爲_id字段生成一個ObjectId。
MongoDB客戶端應添加具有唯一 ObjectId 的 _id 字段。 將 ObjectIds 用於 _id 字段可提供以下額外好處:
- 在mongosh中,可以使用ObjectId.getTimestamp()方法來訪問ObjectId的創建時間
- 對存儲ObjectId值的_id字段進行排序大致相當於按創建時間進行排序
4. 配置文件選項
https://docs.mongodb.com/manual/reference/configuration-options/
Linux中,默認配置文件是 /etc/mongod.conf
啓動時指定配置文件,可以使用 --config 或者 -f 選項
例如:
mongod --config /etc/mongod.conf
或者
mongod -f /etc/mongod.conf
主要的一些配置參見 https://docs.mongodb.com/manual/reference/configuration-options/#core-options
5. MongoDB 包組件
5.1. mongod
mongod 是 MongoDB 系統的主要守護進程。 它處理數據請求,管理數據訪問,並執行後臺管理操作。
https://docs.mongodb.com/manual/reference/program/mongod/
6. CRUD
https://docs.mongodb.com/manual/crud/
https://docs.mongodb.com/manual/reference/command/
https://docs.mongodb.com/manual/reference/method/
7. 存儲
存儲引擎是數據庫的組件,負責管理數據在內存和磁盤中的存儲方式。MongoDB 支持多個存儲引擎,因爲不同的引擎對於特定的工作負載表現更好。選擇合適的存儲引擎會顯着影響應用程序的性能。
7.1. WiredTiger Storage Engine (Default)
WiredTiger 是從 MongoDB 3.2 開始的默認存儲引擎。 它非常適合大多數工作負載,建議用於新部署。 WiredTiger 提供文檔級併發模型、檢查點和壓縮等功能。
從 MongoDB 3.2 開始,WiredTiger 存儲引擎是默認存儲引擎。對於現有部署,如果不指定 --storageEngine 或 storage.engine 設置,則 3.2+ 版本的 mongod 實例可以自動確定 --dbpath 或 storage.dbPath 中用於創建數據文件的存儲引擎。
7.1.1. 文檔級別的併發
WiredTiger 使用文檔級併發控制進行寫入操作。 因此,多個客戶端可以同時修改一個集合的不同文檔。
對於大多數讀寫操作,WiredTiger 使用樂觀併發控制。 WiredTiger 僅在全局、數據庫和集合級別使用意圖鎖。 當存儲引擎檢測到兩個操作之間的衝突時,會引發寫入衝突,導致 MongoDB 透明地重試該操作。
7.1.2. 快照和檢查點
WiredTiger 使用多版本併發控制 (MVCC)。在操作開始時,WiredTiger 會爲操作提供數據的時間點快照。快照呈現內存中數據的一致視圖。
寫入磁盤時,WiredTiger 將快照中的所有數據以一致的方式跨所有數據文件寫入磁盤。現在持久的數據充當數據文件中的檢查點。檢查點確保數據文件在最後一個檢查點之前是一致的,包括最後一個檢查點;即檢查點可以充當恢復點。
從 3.6 版開始,MongoDB 配置 WiredTiger 以每隔 60 秒創建檢查點(即將快照數據寫入磁盤)。在早期版本中,MongoDB 將檢查點設置爲在 WiredTiger 中以 60 秒的間隔或在寫入 2 GB 的日誌數據時發生在用戶數據上,以先發生者爲準。
在寫入新的檢查點期間,之前的檢查點仍然有效。因此,即使 MongoDB 在寫入新檢查點時終止或遇到錯誤,在重新啓動時,MongoDB 也可以從最後一個有效檢查點恢復。
當 WiredTiger 的元數據表被原子更新以引用新的檢查點時,新的檢查點變得可訪問和永久。一旦可以訪問新的檢查點,WiredTiger 就會從舊的檢查點中釋放頁面。
7.1.3. 日誌
WiredTiger 使用預寫日誌(即日誌)結合檢查點來確保數據的持久性。
WiredTiger 日誌保留檢查點之間的所有數據修改。 如果 MongoDB 在檢查點之間退出,它會使用日誌重放自上一個檢查點以來修改的所有數據。
7.1.4. 壓縮
使用 WiredTiger,MongoDB 支持所有集合和索引的壓縮。壓縮以增加 CPU 爲代價最大限度地減少了存儲使用。
默認情況下,WiredTiger 使用 snappy 壓縮庫對所有集合使用塊壓縮,對所有索引使用前綴壓縮。
7.1.5. 內存使用
使用 WiredTiger,MongoDB 同時利用 WiredTiger 內部緩存和文件系統緩存。
從 MongoDB 3.4 開始,默認的 WiredTiger 內部緩存大小是以下兩者中的較大者:
- 50% of (RAM - 1 GB)
- 256 MB
例如,在一個總共有 4GB RAM 的系統上,WiredTiger 緩存將使用 1.5GB 的 RAM (0.5 * (4 GB - 1 GB) = 1.5 GB)。 相反,總共有 1.25 GB RAM 的系統將分配 256 MB 給 WiredTiger 緩存,因爲這是總 RAM 減去 1 GB 的一半以上 (0.5 * (1.25 GB - 1 GB) = 128 MB < 256 MB) 。
7.2. 內存存儲引擎
內存存儲引擎在 MongoDB Enterprise 中可用。它不是將文檔存儲在磁盤上,而是將它們保留在內存中,以獲得更可預測的數據延遲。
從MongoDB Enterprise版本3.2.6開始,內存存儲引擎是64位版本中通用可用性(GA)的一部分。除了一些元數據和診斷數據,內存存儲引擎不維護任何磁盤上的數據,包括配置數據、索引、用戶憑據等。
通過避免磁盤I/O,內存存儲引擎允許更多可預測的數據庫操作延遲。
7.2.1. 指定內存存儲引擎
爲了選擇使用內存存儲引擎,可以這樣操作:
- 命令行中使用 --storageEngine 選項指定 inMemory ,或者 在配置文件中通過設置 storage.engine 的值
- --dbpath 或 storage.dbPath(如果使用配置文件)。儘管內存存儲引擎不會將數據寫入文件系統,但它會在 --dbpath 中維護小型元數據文件和診斷數據以及用於構建大型索引的臨時文件。
例如:
mongod --storageEngine inMemory --dbpath <path>
或者
storage:
engine: inMemory
dbPath: <path>
7.2.2. 併發
內存存儲引擎對寫入操作使用文檔級併發控制。因此,多個客戶端可以同時修改一個集合的不同文檔。
7.2.3. 內存使用
內存存儲引擎要求它的所有數據(包括索引,如果mongod實例是副本集的一部分,則包括oplog,等等)必須符合命令行選項 --inMemorySizeGB 或配置文件中 storage.inMemory.engineConfig.inMemorySizeGB 設置的內存大小。
默認情況下,內存存儲引擎使用 50% 的物理 RAM 減去 1 GB。
例如,內存8G,那麼使用內存存儲引擎的話,默認使用的內存大小最多是 8 × 0.5 - 1 = 3 GB
如果寫入操作會導致數據超過指定的內存大小,MongoDB 會返回錯誤:
"WT_CACHE_FULL: operation would overflow cache"
爲了指定新的內存大小,在配置文件中設置 storage.inMemory.engineConfig.inMemorySizeGB
storage:
engine: inMemory
dbPath: <path>
inMemory:
engineConfig:
inMemorySizeGB: <newSize>
或者使用命令行參數 --inMemorySizeGB
mongod --storageEngine inMemory --dbpath <path> --inMemorySizeGB <newSize>
7.2.4. 持久化
內存存儲引擎是非持久化的,不向持久化存儲寫入數據。非持久數據包括應用程序數據和系統數據,如用戶、權限、索引、副本集配置、分片集羣配置等。
因此,日誌或等待數據變得持久的概念不適用於內存存儲引擎。
7.2.5. 事務
從MongoDB 4.2開始,副本集和分片集羣上都支持事務: 主節點使用 WiredTiger 存儲引擎,並且次要成員使用 WiredTiger 存儲引擎或內存存儲引擎。