`
VerRan
  • 浏览: 458677 次
  • 性别: Icon_minigender_1
  • 来自: 陕西.西安
社区版块
存档分类
最新评论

HSQLDB实现学习笔记-数据库服务器创建

 
阅读更多

前言:

HSQLDB作为一个纯java实现的开源数据库,对于我们在学习数据库实现原理方面有很大的帮助,这里只是对自己学习源码过程中的过程做了简单记录,还处于初步阶段。 通过这一段时间的学习 从大的思路角度,数据库本质上是多个客户端通过socket 客户端与 数据库服务器(soketServer端) 之间进行交互的,数据库服务器端实现了线程池以便更高效的处理客户端连接,这里顺便提一下应用服务器,应用服务器本质上也是客户端通过浏览器发起的连接,应用服务器端建立连接池处理客户端发起的连接这里很早以前写过一篇关于tomcate的文章当时也是初探没有深入研究。 总的来说大的方向就是客户端与服务器端通过soket进行连接通信,服务启动通过serversoket监听客户端的连接,客户端通过socket客户端发起连接请求,这个是大的流程,那么具体的细节要研究的东西就很多了,包含数据是如何存储到数据库的,数据是如何从数据库查询回来的,通过这一段的时间学习代码只解决了一部分疑问还有很多问题值得继续深入研究。

    从数据库本身的角度来讲,其是一直在后台持续运行的一个程序。

    从数据库存储数据的角度来讲,其数据是存储在各种类型的文件中的,当然在实际的处理过程中数据库本本身是有我们理解中的表,索引,视图等的实体的 只是数据 最终本质上是存储在文件汇总的,比如数据文件。

    从数据查询的角度来讲,就是要将数据高效的从数据库中(文件中)查询出来,这里就涉及索引技术,比如hash索引,二叉树 等数据结构的知识。

   从数据存储的角度讲,就是数据如何插入到数据库,最终如何存储到文件中,索引因为插入更新而导致的变化如何处理的,这里涉及二叉树的调整以及平衡等知识。  

 从sql语言的处理角度讲,就是数据库如何去识别sql语言,如何去解析,如何去转换。 

   以及 事物的处理,数据库存储过程,触发器,函数 等其它 功能的支撑,数据库的实现时一个相当复杂的,但是其中很多理论和只是都是我们 以前数据结构、数据库原理学习过的知识,现在回头去看以前学的东西觉得还是很有用的,只是当时我们没有意识到。

 

1数据库服务器创建(Server)

 

1.1功能描述

用于实现数据库服务器,包括数据库服务器相关的属性和操作,属性比如数据库的名字、端口、路径等信息,包含数据的相关操作如启动、停止。

此类有一个内部类ServerThread类

1.2数据库启动

数据库启动本质上是启动了一个serverThread线程

1.2.1     Server->start()

 

publicint start() {
 
        serverThread = new ServerThread("HSQLDB Server ");
 
        if (isDaemon) {
            serverThread.setDaemon(true);
        }
        serverThread.start();
    }
 

 

该线程被设置为守护线程,该线程的run 方法调用server类的run 方法实现数据库的启动。

1.2.2     ServerThread->Run()

(1) 创建一个服务器端口 ServerSocket,通过HsqlSocketFactory创建ServerSocket类

(2) 创建一个线程组,同时让当前的ServerThread作为线程组的父线程。

(3) 打开数据库,获取数据相关参数。

(4) DataBaseManager.getDatabase方法获取数据库信息,先通过数据库(根据路径生成的一个key值)缓存中获取数据库,如果存在则返回,否则直接通过Database类创建新的数据库实例。

(5) DataBase的创建过程中设置数据库状态为关闭、设置数据库类型、绝对路径、相对路径、创建日志对象用于存储操作日志。

(6) 调用database的open方法打开数据库:

 

  

void reopen() {
 
        boolean isNew = false;
 
        setState(DATABASE_OPENING);
 
        try {
            lobManager     = new LobManager(this);
            nameManager    = new HsqlNameManager(this);
            granteeManager = new GranteeManager(this);
            userManager    = new UserManager(this);
            schemaManager  = new SchemaManager(this);
            persistentStoreCollection =
                new PersistentStoreCollectionDatabase(this);
            isReferentialIntegrity = true;
            sessionManager         = new SessionManager(this);
            collation              = collation.newDatabaseInstance();
            dbInfo = DatabaseInformation.newDatabaseInformation(this);
            txManager              = new TransactionManager2PL(this);
 
            lobManager.createSchema();
            sessionManager.getSysLobSession().setSchema(
                SqlInvariants.LOBS_SCHEMA);
            schemaManager.setSchemaChangeTimestamp();
            schemaManager.createSystemTables();
 
            // completed metadata
            logger.open();//关联到数据持久化流程,此步也是打开数据库文件的步骤
 
            isNew = logger.isNewDatabase;
 
            if (isNew) {
                String username = urlProperties.getProperty("user", "SA");
                String password = urlProperties.getProperty("password", "");
 
                userManager.createFirstUser(username, password);
                schemaManager.createPublicSchema();
                logger.checkpoint(false);
            }
 
            lobManager.open();
            dbInfo.setWithContent(true);
 
            checkpointRunner = new CheckpointRunner();
            timeoutRunner    = new TimeoutRunner();
        } catch (Throwable e) {
            logger.close(Database.CLOSEMODE_IMMEDIATELY);
            logger.releaseLock();
            setState(DATABASE_SHUTDOWN);
            clearStructures();
            DatabaseManager.removeDatabase(this);
 
            if (!(e instanceof HsqlException)) {
                e = Error.error(ErrorCode.GENERAL_ERROR, e);
            }
 
            logger.logSevereEvent("could not reopen database", e);
 
            throw (HsqlException) e;
        }
 
        setState(DATABASE_ONLINE);
    }
 

 

1.2.1     客户端请求接收并处理

此部分的入口是在创建完serversoket后执行的,也在run方法中。

try {
            /*
             * This loop is necessary for UNIX w/ Sun Java 1.3 because
             * in that case the socket.close() elsewhere will not
             * interrupt this accept().
             */
            while (socket != null) {
                try {
                    handleConnection(socket.accept());// 接收并处理客户端发起的请求
                } catch (java.io.InterruptedIOException iioe) {}
            }
        } catch (IOException ioe) {
            if (getState() == ServerConstants.SERVER_STATE_ONLINE) {
                setServerError(ioe);
                printError(this + ".run()/handleConnection(): ");
                printStackTrace(ioe);
            }
        } catch (Throwable t) {
            printWithThread(t.toString());
        } finally {
            shutdown(false);    // or maybe getServerError() != null?
        }

 

1.2.2     客户端请求处理步骤

 

  publicvoid handleConnection(Socket s) {
 
        Thread   t;
        Runnable r;
        String   ctn;
 
        printWithThread("handleConnection(" + s + ") entered");
 
        if (!allowConnection(s)) {
            try {
                s.close();
            } catch (Exception e) {}
 
            printWithThread("allowConnection(): connection refused");
            printWithThread("handleConnection() exited");
 
            return;
        }
 
        // Maybe set up socket options, SSL
        // Session tracing/callbacks, etc.
        if (socketFactory != null) {
            socketFactory.configureSocket(s);
        }
 
        if (serverProtocol == ServerConstants.SC_PROTOCOL_HSQL) {
            r   = new ServerConnection(s, this);
            ctn = ((ServerConnection) r).getConnectionThreadName();
        } else {
            r   = new WebServerConnection(s, (WebServer) this);
            ctn = ((WebServerConnection) r).getConnectionThreadName();
        }
 
        t = new Thread(serverConnectionThreadGroup, r, ctn);
 
        t.start();
        printWithThread("handleConnection() exited");
    }

 

(1) 初步判断如是否允许该socket建立连接

(2) 根据服务类型判断创建哪种类型的连接,比如是Server类创建ServerConnection如果是webserver则创建WebServerConnection,每一个连接是一个单独的线程、

(3) 将连接线程加入到线程组中。

1.3数据库创建

此部分是对1.2.2 database.open方法的详细说明

1.3.1     LobManager创建schema

(1) 加载自定义的初始化脚本/org/hsqldb/resources/lob-schema.sql

1.3.2     SchemaManager创建SystemTable

1.3.3     Logger打开日志并且设置为新建数据库日志

1.3.4     UsernManager创建第一个用户

1.3.5     Schemanager创建publicSchema

Schema用于存储hsqldb的所有对象信息

   

 // SCHEMA management
    publicvoid createPublicSchema() {
 
        writeLock.lock();
 
        try {
            HsqlName name = database.nameManager.newHsqlName(null,
                SqlInvariants.PUBLIC_SCHEMA, SchemaObject.SCHEMA);
            Schema schema =
                new Schema(name, database.getGranteeManager().getDBARole());
 
            defaultSchemaHsqlName = schema.getName();
 
            schemaMap.put(schema.getName().name, schema);
        } finally {
            writeLock.unlock();
        }
    }

 

1.3.6  Schema类包含的特性

   

 public Schema(HsqlName name, Grantee owner) {
 
        this.name        = name;
        triggerLookup    = new SchemaObjectSet(SchemaObject.TRIGGER);
        indexLookup      = new SchemaObjectSet(SchemaObject.INDEX);
        constraintLookup = new SchemaObjectSet(SchemaObject.CONSTRAINT);
        tableLookup      = new SchemaObjectSet(SchemaObject.TABLE);
        sequenceLookup   = new SchemaObjectSet(SchemaObject.SEQUENCE);
        typeLookup       = new SchemaObjectSet(SchemaObject.TYPE);
        charsetLookup    = new SchemaObjectSet(SchemaObject.CHARSET);
        collationLookup  = new SchemaObjectSet(SchemaObject.COLLATION);
        procedureLookup  = new SchemaObjectSet(SchemaObject.PROCEDURE);
        functionLookup   = new SchemaObjectSet(SchemaObject.FUNCTION);
        specificRoutineLookup =
            new SchemaObjectSet(SchemaObject.SPECIFIC_ROUTINE);
        assertionLookup = new SchemaObjectSet(SchemaObject.ASSERTION);
        tableList       = (HashMappedList) tableLookup.map;
        sequenceList    = (HashMappedList) sequenceLookup.map;
        name.owner      = owner;
}

 

1.3.7     创建checkPoint生成后台线程

checkpointRunner = new CheckpointRunner();

 

1.3.8  创建timeOut生成后台线程

 

   

timeoutRunner    = new TimeoutRunner();

 

分享到:
评论

相关推荐

    Spring Boot核心技术-笔记-pdf版.zip

    例如,如果项目中存在`HSQLDB`的jar,Spring Boot会自动配置一个内存数据库。 3. **嵌入式Web服务器**:Spring Boot支持内嵌Tomcat、Jetty或Undertow等Web服务器,无需额外部署,简化了开发流程。 4. **Actuator**...

    SpringBoot经典学习笔记_springboot_SpringBoot经典学习笔记_

    SpringBoot经典学习笔记是针对Java开发者的宝贵资源,它涵盖了SpringBoot的核心概念、特性以及实践应用。SpringBoot是由Pivotal团队开发的框架,旨在简化Spring应用的初始搭建以及开发过程,通过“约定优于配置”的...

    SpringBoot经典学习笔记

    在"SpringBoot经典学习笔记"中,你可能会了解到以下关键知识点: 1. **起步依赖(Starter Dependencies)**:SpringBoot通过starter依赖来简化构建配置,比如`spring-boot-starter-web`用于Web应用,`spring-boot-...

    Spring Boot核心技术-笔记-pdf版.pdf

    **Spring Boot核心技术详解** Spring Boot是由Pivotal团队提供的全新框架,其设计目标是为了简化Spring应用的...希望这份学习笔记能帮助你深入理解和掌握Spring Boot的精髓,祝你在Spring Boot的学习之路上一帆风顺!

    有关hsql处理文本数据库的笔记

    HSQL(HyperSQL)是一个开源的关系型数据库管理系统,它支持内存模式、文件模式以及服务器模式,能够处理各种类型的数据,包括文本数据库。这篇笔记将探讨如何使用HSQL处理文本数据库,结合标签"源码"和"工具",我们...

    jBoss+tomcat学习笔记大全,jBoss+tomcat的帮助文档

    ### jBoss + Tomcat 学习笔记大全及帮助文档概览 #### 一、环境搭建与配置 在开始深入探讨jBoss与Tomcat的集成之前,我们先来了解如何搭建基本的开发环境。 ##### 1. Java 环境配置 - **安装 J2SDK1.4+ 和 J2...

    springboot-guides:springboot文档学习笔记

    在"springboot-guides"的学习笔记中,我们可以深入探讨以下几个核心知识点: 1. **起步依赖(Starters)**: SpringBoot通过起步依赖来简化Maven或Gradle的配置,每个起步依赖都是一个包含相关依赖的模块集合,如...

    SpringBootLearn:Spring boot学习过程源码和笔记,原理之后补充

    5. **Spring Data**:Spring Boot与Spring Data结合,可以快速地实现对各种数据库(如JPA、MongoDB等)的操作。Spring Data JPA提供了强大的Repository抽象,简化了数据访问层的代码。 6. **Cloud Connectors**:...

    spring boot

    例如,如果在类路径下发现了`HSQLDB`数据库,Spring Boot将自动配置一个内存数据库连接。 3. **内嵌Web服务器(Embedded Web Server)** Spring Boot支持内嵌Tomcat、Jetty或Undertow等Web服务器,无需额外安装和...

Global site tag (gtag.js) - Google Analytics