diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 2df9d89ea4..a4a70750a3 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -78,15 +78,12 @@ source ~/.bashrc ./install.sh ``` -But you still need to: -- Put the [MySQL JDBC connector](https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar) into `PIXELS_HOME/lib`. -- Modify `PIXELS_HOME/etc/pixels.properties` to ensure the following properties are valid: +But you still need to modify `PIXELS_HOME/etc/pixels.properties` to ensure the following properties are valid: ```properties pixels.var.dir=/home/pixels/opt/pixels/var/ -metadata.db.driver=com.mysql.jdbc.Driver metadata.db.user=pixels metadata.db.password=password -metadata.db.url=jdbc:mysql://localhost:3306/pixels_metadata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull +metadata.db.url=jdbc:derby:/home/pixels/opt/pixels/var/pixels_metadata;create=true metadata.server.port=18888 metadata.server.host=localhost trans.server.port=18889 @@ -145,9 +142,10 @@ Leave the other config parameters as default. Set `cache.enabled` to `false` in `PIXELS_HOME/etc/pixels.properties` if you don't use pixels-cache. -## Install MySQL -MySQL and etcd are used to store the metadata and states of Pixels. MySQL/MariaDB 5.5 or later has been tested. Other forks or variants may also work. -You only need to install one etcd and one MySQL instance, even in a cluster. +## Install MySQL* +Mysql is optional. Pixels uses the embedded database Derby to store the metadata by default. +However, we also support MySQL as the metadata database. +MySQL/MariaDB 5.5 or later has been tested. Other forks or variants may also work. To install MySQL: ```bash @@ -177,8 +175,14 @@ binds the server to localhost thus declines remote connections. Use `scripts/sql/metadata_schema.sql` to create tables in `pixels_metadata`. +Then, put the [MySQL JDBC connector](https://repo1.maven.org/maven2/com/mysql/mysql-connector-j/8.0.33/mysql-connector-j-8.0.33.jar) into `PIXELS_HOME/lib` and set `metadata.db.url=jdbc:mysql://localhost:3306/pixels_metadata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull` +in `PIXELS_HOME/etc/pixels.properties` to enable MySQL as the metadata storage in Pixels. +Change `localhost` in the URL to the hostname of the MySQL server if it is not running on the same node as Pixels coordinator. + ## Install etcd +Etcd is used to store the states of Pixels. + First install go-lang: ```bash sudo apt install golang diff --git a/pixels-common/src/main/java/io/pixelsdb/pixels/common/utils/MetaDBUtil.java b/pixels-common/src/main/java/io/pixelsdb/pixels/common/utils/MetaDBUtil.java index 9fe5e4f0c3..bb2319c388 100644 --- a/pixels-common/src/main/java/io/pixelsdb/pixels/common/utils/MetaDBUtil.java +++ b/pixels-common/src/main/java/io/pixelsdb/pixels/common/utils/MetaDBUtil.java @@ -55,12 +55,10 @@ private MetaDBUtil() try { ConfigFactory config = ConfigFactory.Instance(); - String driver = config.getProperty("metadata.db.driver"); url = config.getProperty("metadata.db.url"); user = config.getProperty("metadata.db.user"); pass = config.getProperty("metadata.db.password"); - Class.forName(driver); this.connection = DriverManager.getConnection(url, user, pass); } catch (Exception e) diff --git a/pixels-common/src/main/resources/pixels.properties b/pixels-common/src/main/resources/pixels.properties index 74915a9882..a9934f399b 100644 --- a/pixels-common/src/main/resources/pixels.properties +++ b/pixels-common/src/main/resources/pixels.properties @@ -2,10 +2,10 @@ # pixels.var.dir is where the lock files are created pixels.var.dir=/home/pixels/opt/pixels/var/ # metadata database connection properties -metadata.db.driver=com.mysql.cj.jdbc.Driver metadata.db.user=pixels metadata.db.password=password -metadata.db.url=jdbc:mysql://localhost:3306/pixels_metadata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull +#metadata.db.url=jdbc:mysql://localhost:3306/pixels_metadata?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull +metadata.db.url=jdbc:derby:/home/pixels/opt/pixels/var/pixels_metadata;create=true # metadata server host and port metadata.server.port=18888 metadata.server.host=localhost diff --git a/pixels-common/src/test/java/io/pixelsdb/pixels/common/TestMetadataService.java b/pixels-common/src/test/java/io/pixelsdb/pixels/common/metadata/TestMetadataService.java similarity index 97% rename from pixels-common/src/test/java/io/pixelsdb/pixels/common/TestMetadataService.java rename to pixels-common/src/test/java/io/pixelsdb/pixels/common/metadata/TestMetadataService.java index 6f4ec327c9..56aebb4624 100644 --- a/pixels-common/src/test/java/io/pixelsdb/pixels/common/TestMetadataService.java +++ b/pixels-common/src/test/java/io/pixelsdb/pixels/common/metadata/TestMetadataService.java @@ -17,11 +17,10 @@ * License along with Pixels. If not, see * . */ -package io.pixelsdb.pixels.common; +package io.pixelsdb.pixels.common.metadata; import com.alibaba.fastjson.JSON; import io.pixelsdb.pixels.common.exception.MetadataException; -import io.pixelsdb.pixels.common.metadata.MetadataService; import io.pixelsdb.pixels.common.metadata.domain.*; import org.junit.Before; import org.junit.Test; diff --git a/pixels-daemon/pom.xml b/pixels-daemon/pom.xml index 987b089e80..4dcac2147e 100644 --- a/pixels-daemon/pom.xml +++ b/pixels-daemon/pom.xml @@ -87,6 +87,11 @@ jetcd-core + + org.apache.derby + derby + + io.trino diff --git a/pixels-daemon/src/test/java/io/pixelsdb/pixels/daemon/metadata/dao/TestRdbDaos.java b/pixels-daemon/src/test/java/io/pixelsdb/pixels/daemon/metadata/dao/TestRdbDaos.java index f8dcf3367b..673953ae14 100644 --- a/pixels-daemon/src/test/java/io/pixelsdb/pixels/daemon/metadata/dao/TestRdbDaos.java +++ b/pixels-daemon/src/test/java/io/pixelsdb/pixels/daemon/metadata/dao/TestRdbDaos.java @@ -21,16 +21,34 @@ import io.pixelsdb.pixels.common.metadata.domain.Layout; import io.pixelsdb.pixels.common.metadata.domain.Ordered; +import io.pixelsdb.pixels.common.utils.MetaDBUtil; import io.pixelsdb.pixels.daemon.MetadataProto; import org.junit.Test; import java.io.*; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.HashSet; import java.util.List; import java.util.Set; public class TestRdbDaos { + @Test + public void testRdbConnection() throws SQLException + { + MetaDBUtil db = MetaDBUtil.Instance(); + Connection conn = db.getConnection(); + Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery("VALUES 1"); // VALUES 1 for derby, SELCT 1 for MySQL + assert rs != null && rs.next(); + assert rs.getInt(1) == 1; + assert !rs.next(); + conn.close(); + } + @Test public void testSchema () { diff --git a/pixels-retina/src/test/java/io/pixelsdb/pixels/retina/TestStorageGarbageCollector.java b/pixels-retina/src/test/java/io/pixelsdb/pixels/retina/TestStorageGarbageCollector.java index 9f55fd1b47..da9365d11f 100644 --- a/pixels-retina/src/test/java/io/pixelsdb/pixels/retina/TestStorageGarbageCollector.java +++ b/pixels-retina/src/test/java/io/pixelsdb/pixels/retina/TestStorageGarbageCollector.java @@ -19,24 +19,18 @@ */ package io.pixelsdb.pixels.retina; +import com.google.common.collect.ImmutableList; import io.pixelsdb.pixels.common.index.service.LocalIndexService; import io.pixelsdb.pixels.common.metadata.MetadataService; -import io.pixelsdb.pixels.common.utils.CheckpointFileIO; -import io.pixelsdb.pixels.common.utils.ConfigFactory; -import io.pixelsdb.pixels.common.utils.MetaDBUtil; -import io.pixelsdb.pixels.common.utils.PixelsFileNameUtils; -import io.pixelsdb.pixels.common.utils.RetinaUtils; import io.pixelsdb.pixels.common.metadata.domain.Column; import io.pixelsdb.pixels.common.metadata.domain.File; import io.pixelsdb.pixels.common.metadata.domain.Layout; import io.pixelsdb.pixels.common.physical.Storage; import io.pixelsdb.pixels.common.physical.StorageFactory; -import io.pixelsdb.pixels.core.PixelsFooterCache; -import io.pixelsdb.pixels.core.PixelsReader; -import io.pixelsdb.pixels.core.PixelsReaderImpl; -import io.pixelsdb.pixels.core.PixelsWriter; -import io.pixelsdb.pixels.core.PixelsWriterImpl; -import io.pixelsdb.pixels.core.TypeDescription; +import io.pixelsdb.pixels.common.utils.ConfigFactory; +import io.pixelsdb.pixels.common.utils.PixelsFileNameUtils; +import io.pixelsdb.pixels.common.utils.RetinaUtils; +import io.pixelsdb.pixels.core.*; import io.pixelsdb.pixels.core.encoding.EncodingLevel; import io.pixelsdb.pixels.core.reader.PixelsReaderOption; import io.pixelsdb.pixels.core.reader.PixelsRecordReader; @@ -44,37 +38,20 @@ import io.pixelsdb.pixels.core.vector.DoubleColumnVector; import io.pixelsdb.pixels.core.vector.LongColumnVector; import io.pixelsdb.pixels.core.vector.VectorizedRowBatch; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; +import org.junit.*; import java.io.IOException; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; -import java.sql.PreparedStatement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; /** * Tests for {@link StorageGarbageCollector}, covering scan/grouping, data rewrite, @@ -3313,8 +3290,7 @@ private Map getRgVisibilityMap() // Helpers: catalog registration // ======================================================================= - private long registerTestFile(String name, File.Type type, - int numRg, long minRow, long maxRow) + private long registerTestFile(String name, File.Type type, int numRg, long minRow, long maxRow) throws Exception { File f = new File(); @@ -3330,29 +3306,22 @@ private long registerTestFile(String name, File.Type type, return id; } - private long insertRawFileWithType(String name, int fileType, - int numRg, long minRow, long maxRow) - throws Exception + private long insertRawFileWithType(String name, int fileType, int numRg, long minRow, long maxRow) throws Exception { - String sql = "INSERT INTO FILES(FILE_NAME, FILE_TYPE, FILE_NUM_RG, FILE_MIN_ROW_ID, FILE_MAX_ROW_ID, PATHS_PATH_ID) " + - "VALUES (?, ?, ?, ?, ?, ?)"; - try (PreparedStatement pst = MetaDBUtil.Instance().getConnection().prepareStatement(sql)) - { - pst.setString(1, name); - pst.setInt(2, fileType); - pst.setInt(3, numRg); - pst.setLong(4, minRow); - pst.setLong(5, maxRow); - pst.setLong(6, testPathId); - assertEquals("raw test file insert should affect one row", 1, pst.executeUpdate()); - } + File file = new File(); + file.setName(name); + file.setType(File.Type.valueOf(fileType)); + file.setNumRowGroup(numRg); + file.setMinRowId(minRow); + file.setMaxRowId(maxRow); + file.setPathId(testPathId); + metadataService.addFiles(ImmutableList.of(file)); long id = metadataService.getFileId(testOrderedPathUri + "/" + name); assertTrue(name + " must have valid id", id > 0); return id; } - private long[] registerTestFiles(String[] names, File.Type[] types, - int[] numRgs, long[] minRows, long[] maxRows) + private long[] registerTestFiles(String[] names, File.Type[] types, int[] numRgs, long[] minRows, long[] maxRows) throws Exception { List files = new ArrayList<>(); @@ -3428,8 +3397,7 @@ private static void assertNoIndexSwitchingTask(List tasks) // Helpers: GC factory for grouping tests // ======================================================================= - private static StorageGarbageCollector newGcForGrouping( - long targetFileSize, int maxFilesPerGroup, int maxGroups) + private static StorageGarbageCollector newGcForGrouping(long targetFileSize, int maxFilesPerGroup, int maxGroups) { return new StorageGarbageCollector( null, null, null, 0.5, targetFileSize, maxFilesPerGroup, maxGroups, @@ -3448,8 +3416,7 @@ private static StorageGarbageCollector newGcForGrouping( *
  • The sentinel entry equals the expected total surviving rows
  • * */ - private static void assertRewriteResultConsistency( - StorageGarbageCollector.RewriteResult result, int expectedTotalRows) + private static void assertRewriteResultConsistency(StorageGarbageCollector.RewriteResult result, int expectedTotalRows) { assertTrue("newFileRgCount must be at least 1", result.newFileRgCount >= 1); assertEquals(result.newFileRgCount, result.newFileRgActualRecordNums.length); @@ -3579,8 +3546,7 @@ private static String writeTestFile(String fileName, TypeDescription schema, * the Pixels writer flushes one RG per call. Row values are sequential integers * starting from 0. */ - private static String writeTestFileMultiRg(String fileName, TypeDescription schema, - int numRgs, int rowsPerRg) throws Exception + private static String writeTestFileMultiRg(String fileName, TypeDescription schema, int numRgs, int rowsPerRg) throws Exception { return writeTestFileMultiRg(fileName, schema, numRgs, rowsPerRg, 10_000); } @@ -3671,8 +3637,7 @@ private static long[][] readAllRows(String path, TypeDescription schema, * {@code pathId} is set to {@link #testPathId} so that {@code addFiles} satisfies * the foreign key constraint against the PATHS table. */ - private static StorageGarbageCollector.FileGroup makeGroup( - long fileId, String filePath, TypeDescription schema) throws Exception + private static StorageGarbageCollector.FileGroup makeGroup(long fileId, String filePath, TypeDescription schema) throws Exception { int rgCount; try (PixelsReader r = PixelsReaderImpl.newBuilder() @@ -3701,10 +3666,8 @@ private static StorageGarbageCollector.FileGroup makeGroup( * {@link StorageGarbageCollector.FileCandidate} objects backed by distinct files. * Both files share the same {@code (tableId=1, virtualNodeId=0)}. */ - private static StorageGarbageCollector.FileGroup makeMultiFileGroup( - TypeDescription schema, - long fileIdA, String pathA, - long fileIdB, String pathB) throws Exception + private static StorageGarbageCollector.FileGroup makeMultiFileGroup(TypeDescription schema, + long fileIdA, String pathA, long fileIdB, String pathB) throws Exception { List candidates = new ArrayList<>(); for (long[] pair : new long[][]{{fileIdA, 0}, {fileIdB, 0}}) diff --git a/pom.xml b/pom.xml index 92e8d7c814..8cc964974b 100644 --- a/pom.xml +++ b/pom.xml @@ -118,6 +118,8 @@ 0.7.7 + + 10.14.2.0 5.13.0 1.3.2 0.16.0 @@ -351,6 +353,13 @@ ${dep.trino.version}
    + + + org.apache.derby + derby + ${dep.derby.version} + + io.prometheus