Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.

Commit 96c12a3

Browse files
committed
sql: implement memory management system for caches
This PR implements a memory management system, intended to have control over the allocated memory for caches so that they can be freed at any moment and we can avoid out of memory errors. The main changes are the following: - MemoryManager in the sql package, which is just the component that tracks all caches. Memory of all freeable caches can be freed using the Free method of this component. The only way to instantiate new caches is using the NewXXXCache methods. - Rows, history and LRU cache implementations, accessed using the NewXXXCache methods of MemoryManager. - Reporters, which is a component that reports the maximum amount of memory the program is allowed to use and the currently used memory. This interface is meant for making testing easier. There is a default ProcessMemory reporter that returns the memory used by the process and the maximum memory defined in the `MAX_MEMORY` environment variable. - MemoryManager is passed down to every component through *sql.Context, which meant a little more boilerplate on the server SessionBuilder. - GroupBy, Sort, Distinct and Join now use the provided APIs of memory and cache management for their in-memory computations. Caveats: - We need to think of a good default so that memory usage won't grow forever and crash eventually, which is the behaviour when MAX_MEMORY is 0. Signed-off-by: Miguel Molina <[email protected]>
1 parent 875590d commit 96c12a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1079
-448
lines changed

.travis.yml

-10
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,11 @@ env:
1010
addons:
1111
apt:
1212
packages:
13-
- libonig-dev
1413
- libmysqlclient-dev
1514

1615
matrix:
1716
fast_finish: true
1817

19-
sudo: required
20-
21-
services:
22-
- docker
23-
24-
install:
25-
- go get ./...
26-
- make dependencies
27-
2818
before_script:
2919
- sudo service mysql stop
3020

README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ SET <variable name> = <value>
141141
|:-----|:-----|:------------|
142142
|`INMEMORY_JOINS`|environment|If set it will perform all joins in memory. Default is off.|
143143
|`inmemory_joins`|session|If set it will perform all joins in memory. Default is off. This has precedence over `INMEMORY_JOINS`.|
144-
|`MAX_MEMORY_JOIN`|environment|The maximum number of memory, in megabytes, that can be consumed by go-mysql-server before switching to multipass mode in joins. Default is the 20% of all available physical memory.|
145-
|`max_memory_joins`|session|The maximum number of memory, in megabytes, that can be consumed by go-mysql-server before switching to multipass mode in joins. Default is the 20% of all available physical memory. This has precedence over `MAX_MEMORY_JOIN`.|
144+
|`MAX_MEMORY`|environment|The maximum number of memory, in megabytes, that can be consumed by go-mysql-server. Any in-memory caches or computations will no longer try to use memory when the limit is reached. Note that this may cause certain queries to fail if there is not enough memory available, such as queries using DISTINCT, ORDER BY or GROUP BY with groupings.|
146145
|`DEBUG_ANALYZER`|environment|If set, the analyzer will print debug messages. Default is off.|
147146
|`PILOSA_INDEX_THREADS`|environment|Number of threads used in index creation. Default is the number of cores available in the machine.|
148147
|`pilosa_index_threads`|environment|Number of threads used in index creation. Default is the number of cores available in the machine. This has precedence over `PILOSA_INDEX_THREADS`.|
@@ -176,14 +175,14 @@ func main() {
176175
s.Start()
177176
}
178177

179-
func createTestDatabase() *mem.Database {
178+
func createTestDatabase() *memory.Database {
180179
const (
181180
dbName = "test"
182181
tableName = "mytable"
183182
)
184183

185-
db := mem.NewDatabase(dbName)
186-
table := mem.NewTable(tableName, sql.Schema{
184+
db := memory.NewDatabase(dbName)
185+
table := memory.NewTable(tableName, sql.Schema{
187186
{Name: "name", Type: sql.Text, Nullable: false, Source: tableName},
188187
{Name: "email", Type: sql.Text, Nullable: false, Source: tableName},
189188
{Name: "phone_numbers", Type: sql.JSON, Nullable: false, Source: tableName},

_example/main.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55

66
sqle "github.com/src-d/go-mysql-server"
77
"github.com/src-d/go-mysql-server/auth"
8-
"github.com/src-d/go-mysql-server/mem"
8+
"github.com/src-d/go-mysql-server/memory"
99
"github.com/src-d/go-mysql-server/server"
1010
"github.com/src-d/go-mysql-server/sql"
1111
)
@@ -42,14 +42,14 @@ func main() {
4242
s.Start()
4343
}
4444

45-
func createTestDatabase() *mem.Database {
45+
func createTestDatabase() *memory.Database {
4646
const (
4747
dbName = "mydb"
4848
tableName = "mytable"
4949
)
5050

51-
db := mem.NewDatabase(dbName)
52-
table := mem.NewTable(tableName, sql.Schema{
51+
db := memory.NewDatabase(dbName)
52+
table := memory.NewTable(tableName, sql.Schema{
5353
{Name: "name", Type: sql.Text, Nullable: false, Source: tableName},
5454
{Name: "email", Type: sql.Text, Nullable: false, Source: tableName},
5555
{Name: "phone_numbers", Type: sql.JSON, Nullable: false, Source: tableName},

_integration/ruby/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
vendor/bundle:
2+
gem install bundler --version=1.16.5
23
bundler install --path vendor/bundle
34

45
dependencies: vendor/bundle
56

67
test: dependencies
78
bundler exec ruby mysql_test.rb
89

9-
.PHONY: test
10+
.PHONY: test

auth/common_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"github.com/stretchr/testify/require"
1212
sqle "github.com/src-d/go-mysql-server"
1313
"github.com/src-d/go-mysql-server/auth"
14-
"github.com/src-d/go-mysql-server/mem"
14+
"github.com/src-d/go-mysql-server/memory"
1515
"github.com/src-d/go-mysql-server/server"
1616
"github.com/src-d/go-mysql-server/sql"
1717
"github.com/src-d/go-mysql-server/sql/analyzer"
@@ -21,13 +21,13 @@ import (
2121
const port = 3336
2222

2323
func authEngine(au auth.Auth) (string, *sqle.Engine, error) {
24-
db := mem.NewDatabase("test")
24+
db := memory.NewDatabase("test")
2525
catalog := sql.NewCatalog()
2626
catalog.AddDatabase(db)
2727

2828
tblName := "test"
2929

30-
table := mem.NewTable(tblName, sql.Schema{
30+
table := memory.NewTable(tblName, sql.Schema{
3131
{Name: "id", Type: sql.Text, Nullable: false, Source: tblName},
3232
{Name: "name", Type: sql.Text, Nullable: false, Source: tblName},
3333
})

benchmark/tpc_h_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ import (
1010
"path/filepath"
1111
"testing"
1212

13-
"github.com/src-d/go-mysql-server"
13+
sqle "github.com/src-d/go-mysql-server"
1414

15-
"github.com/src-d/go-mysql-server/mem"
15+
"github.com/src-d/go-mysql-server/memory"
1616
"github.com/src-d/go-mysql-server/sql"
1717
)
1818

@@ -83,11 +83,11 @@ func executeQueries(b *testing.B, e *sqle.Engine) error {
8383
}
8484

8585
func genDB(b *testing.B) (sql.Database, error) {
86-
db := mem.NewDatabase("tpch")
86+
db := memory.NewDatabase("tpch")
8787

8888
for _, m := range tpchTableMetadata {
8989
b.Log("generating table", m.name)
90-
t := mem.NewTable(m.name, m.schema)
90+
t := memory.NewTable(m.name, m.schema)
9191
if err := insertDataToTable(m.name, t, len(m.schema)); err != nil {
9292
return nil, err
9393
}
@@ -98,7 +98,7 @@ func genDB(b *testing.B) (sql.Database, error) {
9898
return db, nil
9999
}
100100

101-
func insertDataToTable(name string, t *mem.Table, columnCount int) error {
101+
func insertDataToTable(name string, t *memory.Table, columnCount int) error {
102102
f, err := os.Open(name + ".tbl")
103103
if err != nil {
104104
return err

0 commit comments

Comments
 (0)